亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java并發(fā)包線程池ThreadPoolExecutor的實(shí)現(xiàn)

 更新時(shí)間:2022年04月02日 10:42:39   作者:派大大大星  
本文主要介紹了Java并發(fā)包線程池ThreadPoolExecutor的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

線程池主要解決兩個(gè)問(wèn)題:一是當(dāng)執(zhí)行大量異步任務(wù)時(shí)線程池能夠提供較好的性能。在不使用線程池時(shí),每當(dāng)需要執(zhí)行異步任務(wù)時(shí)直接new一個(gè)線程來(lái)運(yùn)行,而線程的創(chuàng)建和銷毀都是需要開(kāi)銷的。線程池里面的線程是可復(fù)用的,不需要每次執(zhí)行異步任務(wù)時(shí)都重新創(chuàng)建和銷毀線程。二是線程池提供了一種資源限制和管理手段,比如可以限制線程的個(gè)數(shù),動(dòng)態(tài)新增線程等。每個(gè)ThreadPoolExecutor也保留了一些基本的統(tǒng)計(jì)數(shù)據(jù),比如當(dāng)前線程池完成的任務(wù)數(shù)目等。

我們首先來(lái)看一下類圖

Excecutor是一個(gè)工具類,里面提供了許多靜態(tài)方法,這些方法根據(jù)用戶選擇返回不同的線程池實(shí)例。ThreadPool繼承了AbstractExecutorService。

下面我們看一下源碼,

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY ? = (1 << COUNT_BITS) - 1;

// runState is stored in the high-order bits
private static final int RUNNING ? ?= -1 << COUNT_BITS;
private static final int SHUTDOWN ? = ?0 << COUNT_BITS;
private static final int STOP ? ? ? = ?1 << COUNT_BITS;
private static final int TIDYING ? ?= ?2 << COUNT_BITS;
private static final int TERMINATED = ?3 << COUNT_BITS;

成員變量ctl是一個(gè)Integer的原子變量,用來(lái)記錄當(dāng)前線程池狀態(tài)和線程池中的線程個(gè)數(shù),有點(diǎn)類似于ReentrantReadWriteLock使用一個(gè)變量來(lái)保存兩種信息。

線程池一共有五種狀態(tài):

  • RUNNING:能接受新任務(wù),并且處理阻塞隊(duì)列里面的任務(wù)
  • SHUTDOWN:拒絕接受新任務(wù)但是處理阻塞隊(duì)列里的任務(wù)
  • STOP:拒絕新任務(wù)并且拋棄阻塞隊(duì)列里的任務(wù)
  • TIDYING:所有任務(wù)都執(zhí)行完(包含阻塞隊(duì)列里面的任務(wù))后當(dāng)前線程池活動(dòng)線程數(shù)為0,將要調(diào)用terminated方法。
  • TERMINATED:終止?fàn)顟B(tài)。terminated方法調(diào)用完成以后的狀態(tài)。

線程池狀態(tài)轉(zhuǎn)換如下:

  • RUNNING->SHUTDOWN:顯示調(diào)用shutdown方法,或者隱式調(diào)用finalize()方法里的shutdown()方法。
  • RUNNINGSHUTDOWN->STOP:顯示調(diào)用shutdown方法
  • SHUTDOWN->TIDYING:當(dāng)線程池和任務(wù)隊(duì)列都為空時(shí)
  • STOP->TIDYING:當(dāng)線程池為空時(shí)
  • TIDYING->TERMINATED:Terminated() hook方法執(zhí)行完畢時(shí)

線程池的使用

合理利用線程池能夠帶來(lái)三個(gè)好處:

  • 降低資源消耗。減少了創(chuàng)建和銷毀線程的次數(shù),每個(gè)工作線程都可以被重復(fù)利用,可執(zhí)行多個(gè)任務(wù)。
  • 提高響應(yīng)速度。當(dāng)任務(wù)到達(dá)時(shí),任務(wù)可以不需要的等到線程創(chuàng)建就能立即執(zhí)行。
  • 提高線程的可管理性??梢愿鶕?jù)系統(tǒng)的承受能力,調(diào)整線程池中工作線線程的數(shù)目,防止因?yàn)橄倪^(guò)多的內(nèi)存,而把服務(wù)器累趴下(每個(gè)線程需要大約1MB內(nèi)存,線程開(kāi)的越多,消耗的內(nèi)存也就越大,最后死機(jī))。

在java.util.concurrent.Executors線程工廠類里面提供了一些靜態(tài)工廠,生成一些常用的線程池。官方建議使用Executors工程類來(lái)創(chuàng)建線程池對(duì)象。
Executors類中有個(gè)創(chuàng)建線程池的方法如下:

  • public static ExecutorService newFixedThreadPool(int nThreads):返回線程池對(duì)象。(創(chuàng)建的是有界線程池,也就是池中的線程個(gè)數(shù)可以指定最大數(shù)量)

獲取到了一個(gè)線程池ExecutorService 對(duì)象,那么怎么使用呢,在這里定義了一個(gè)使用線程池對(duì)象的方法如下:

  • public Future<?> submit(Runnable task):獲取線程池中的某一個(gè)線程對(duì)象,并執(zhí)行

Future接口:用來(lái)記錄線程任務(wù)執(zhí)行完畢后產(chǎn)生的結(jié)果。

使用線程池中線程對(duì)象的步驟:

  • 創(chuàng)建線程池對(duì)象。
  • 創(chuàng)建Runnable接口子類對(duì)象。(task)
  • 提交Runnable接口子類對(duì)象。(take task)
  • 關(guān)閉線程池(一般不做)。

Runnable實(shí)現(xiàn)類代碼:

public class MyRunnable implements Runnable {
? ? @Override
? ? public void run() {
? ? ? ? System.out.println("我要一個(gè)教練");
? ? ? ? try {
? ? ? ? ? ? Thread.sleep(2000);
? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? System.out.println("教練來(lái)了: " + Thread.currentThread().getName());
? ? ? ? System.out.println("教我游泳,交完后,教練回到了游泳池");
? ? }
}

public class ThreadPoolDemo {
? ? public static void main(String[] args) {
? ? ? ? // 創(chuàng)建線程池對(duì)象
? ? ? ? ExecutorService service = Executors.newFixedThreadPool(2);//包含2個(gè)線程對(duì)象
? ? ? ? // 創(chuàng)建Runnable實(shí)例對(duì)象
? ? ? ? MyRunnable r = new MyRunnable();

? ? ? ? //自己創(chuàng)建線程對(duì)象的方式
? ? ? ? // Thread t = new Thread(r);
? ? ? ? // t.start(); ---> 調(diào)用MyRunnable中的run()

? ? ? ? // 從線程池中獲取線程對(duì)象,然后調(diào)用MyRunnable中的run()
? ? ? ? service.submit(r);
? ? ? ? // 再獲取個(gè)線程對(duì)象,調(diào)用MyRunnable中的run()
? ? ? ? service.submit(r);
? ? ? ? service.submit(r);
? ? ? ? // 注意:submit方法調(diào)用結(jié)束后,程序并不終止,是因?yàn)榫€程池控制了線程的關(guān)閉。
? ? ? ? // 將使用完的線程又歸還到了線程池中
? ? ? ? // 關(guān)閉線程池
? ? ? ? //service.shutdown();
? ? }
}

Callable測(cè)試代碼:

<T> Future<T> submit(Callable<T> task) : 獲取線程池中的某一個(gè)線程對(duì)象,并執(zhí)行.
Future : 表示計(jì)算的結(jié)果.

V get()   : 獲取計(jì)算完成的結(jié)果。

public class ThreadPoolDemo2 {
? ? public static void main(String[] args) throws Exception {
? ? ? ? // 創(chuàng)建線程池對(duì)象
? ? ? ExecutorService service = Executors.newFixedThreadPool(2);//包含2個(gè)線程對(duì)象

? ? ? ? // 創(chuàng)建Runnable實(shí)例對(duì)象
? ? ? ? Callable<Double> c = new Callable<Double>() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public Double call() throws Exception {
? ? ? ? ? ? ? ? return Math.random();
? ? ? ? ? ? }
? ? ? ? };

? ? ? ? // 從線程池中獲取線程對(duì)象,然后調(diào)用Callable中的call()
? ? ? ? Future<Double> f1 = service.submit(c);
? ? ? ? // Futur 調(diào)用get() 獲取運(yùn)算結(jié)果
? ? ? ? System.out.println(f1.get());

? ? ? ? Future<Double> f2 = service.submit(c);
? ? ? ? System.out.println(f2.get());

? ? ? ? Future<Double> f3 = service.submit(c);
? ? ? ? System.out.println(f3.get());
? ? }
}

線程池的練習(xí)

public class Demo04 {
? ? public static void main(String[] args) throws ExecutionException, InterruptedException {
? ? ? ? ExecutorService pool = Executors.newFixedThreadPool(3);

? ? ? ? SumCallable sc = new SumCallable(100);
? ? ? ? Future<Integer> fu = pool.submit(sc);
? ? ? ? Integer integer = fu.get();
? ? ? ? System.out.println("結(jié)果: " + integer);
? ? ? ??
? ? ? ? SumCallable sc2 = new SumCallable(200);
? ? ? ? Future<Integer> fu2 = pool.submit(sc2);
? ? ? ? Integer integer2 = fu2.get();
? ? ? ? System.out.println("結(jié)果: " + integer2);

? ? ? ? pool.shutdown();
? ? }
}
public class SumCallable implements Callable<Integer> {
? ? private int n;

? ? public SumCallable(int n) {
? ? ? ? this.n = n;
? ? }

? ? @Override
? ? public Integer call() throws Exception {
? ? ? ? // 求1-n的和?
? ? ? ? int sum = 0;
? ? ? ? for (int i = 1; i <= n; i++) {
? ? ? ? ? ? sum += i;
? ? ? ? }
? ? ? ? return sum;
? ? }
}

到此這篇關(guān)于Java并發(fā)包線程池ThreadPoolExecutor的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java并發(fā)包線程池ThreadPoolExecutor內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java自旋鎖的實(shí)現(xiàn)示例

    Java自旋鎖的實(shí)現(xiàn)示例

    自旋鎖是一種特殊的鎖,用于解決多線程同步問(wèn)題,本文主要介紹了Java自旋鎖的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • Java?C++題解leetcode817鏈表組件示例

    Java?C++題解leetcode817鏈表組件示例

    這篇文章主要為大家介紹了Java?C++題解leetcode817鏈表組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Java編程實(shí)現(xiàn)基于TCP協(xié)議的Socket聊天室示例

    Java編程實(shí)現(xiàn)基于TCP協(xié)議的Socket聊天室示例

    這篇文章主要介紹了Java編程實(shí)現(xiàn)基于TCP協(xié)議的Socket聊天室,結(jié)合實(shí)例形式詳細(xì)分析了java基于TCP協(xié)議的Socket聊天室客戶端與服務(wù)器端相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2018-01-01
  • java遞歸算法的實(shí)例詳解

    java遞歸算法的實(shí)例詳解

    在本篇文章里小編給大家整理了關(guān)于java遞歸算法的實(shí)例內(nèi)容,以及相關(guān)知識(shí)點(diǎn)總結(jié),需要的朋友們可以學(xué)習(xí)下。
    2020-02-02
  • IntelliJ IDEA中查看文件內(nèi)所有已聲明的方法(類似eclipse的outline)

    IntelliJ IDEA中查看文件內(nèi)所有已聲明的方法(類似eclipse的outline)

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中查看文件內(nèi)所有已聲明的方法(類似eclipse的outline),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • SpringBoot Admin2.0 集成Arthas的實(shí)現(xiàn)步驟

    SpringBoot Admin2.0 集成Arthas的實(shí)現(xiàn)步驟

    這篇文章主要介紹了SpringBoot Admin2.0 集成Arthas的實(shí)現(xiàn)步驟,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot框架,感興趣的朋友可以了解下
    2021-04-04
  • IDEA創(chuàng)建springboot + mybatis項(xiàng)目全過(guò)程(步驟詳解)

    IDEA創(chuàng)建springboot + mybatis項(xiàng)目全過(guò)程(步驟詳解)

    這篇文章主要介紹了IDEA創(chuàng)建springboot + mybatis項(xiàng)目全過(guò)程及步驟詳解,本文通圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • java定時(shí)任務(wù)的實(shí)現(xiàn)方法

    java定時(shí)任務(wù)的實(shí)現(xiàn)方法

    java定時(shí)任務(wù)的實(shí)現(xiàn)方法,需要的朋友可以參考一下
    2013-03-03
  • SpringBoot詳細(xì)講解如何創(chuàng)建及刷新Spring容器bean

    SpringBoot詳細(xì)講解如何創(chuàng)建及刷新Spring容器bean

    前面看spring源碼時(shí)可以發(fā)現(xiàn)refresh()方法十分重要。在這個(gè)方法中會(huì)加載beanDefinition,同時(shí)創(chuàng)建bean對(duì)象。那么在springboot中有沒(méi)有使用這個(gè)refresh()方法呢
    2022-06-06
  • Flink狀態(tài)和容錯(cuò)源碼解析

    Flink狀態(tài)和容錯(cuò)源碼解析

    這篇文章主要為大家介紹了Flink狀態(tài)和容錯(cuò)源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論