最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

我們首先來看一下類圖

Excecutor是一個工具類,里面提供了許多靜態(tài)方法,這些方法根據(jù)用戶選擇返回不同的線程池實例。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是一個Integer的原子變量,用來記錄當前線程池狀態(tài)和線程池中的線程個數(shù),有點類似于ReentrantReadWriteLock使用一個變量來保存兩種信息。

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

  • RUNNING:能接受新任務,并且處理阻塞隊列里面的任務
  • SHUTDOWN:拒絕接受新任務但是處理阻塞隊列里的任務
  • STOP:拒絕新任務并且拋棄阻塞隊列里的任務
  • TIDYING:所有任務都執(zhí)行完(包含阻塞隊列里面的任務)后當前線程池活動線程數(shù)為0,將要調(diào)用terminated方法。
  • TERMINATED:終止狀態(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:當線程池和任務隊列都為空時
  • STOP->TIDYING:當線程池為空時
  • TIDYING->TERMINATED:Terminated() hook方法執(zhí)行完畢時

線程池的使用

合理利用線程池能夠帶來三個好處:

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

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

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

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

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

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

使用線程池中線程對象的步驟:

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

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

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

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

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

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

Callable測試代碼:

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

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

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

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

? ? ? ? // 從線程池中獲取線程對象,然后調(diào)用Callable中的call()
? ? ? ? Future<Double> f1 = service.submit(c);
? ? ? ? // Futur 調(diào)用get() 獲取運算結(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());
? ? }
}

線程池的練習

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的實現(xiàn)的文章就介紹到這了,更多相關(guān)Java并發(fā)包線程池ThreadPoolExecutor內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解IDEA使用Maven項目不能加入本地Jar包的解決方法

    詳解IDEA使用Maven項目不能加入本地Jar包的解決方法

    這篇文章主要介紹了詳解IDEA使用Maven項目不能加入本地Jar包的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Java設計模式之原型模式詳細解讀

    Java設計模式之原型模式詳細解讀

    這篇文章主要介紹了Java設計模式之原型模式詳細解讀,原型模式屬于創(chuàng)建型設計模式,用于創(chuàng)建重復的對象,且同時又保證了性能,該設計模式的好處是將對象的創(chuàng)建與調(diào)用方分離,需要的朋友可以參考下
    2023-12-12
  • Java基于ReadWriteLock實現(xiàn)鎖的應用

    Java基于ReadWriteLock實現(xiàn)鎖的應用

    這篇文章主要介紹了Java基于ReadWriteLock實現(xiàn)鎖的應用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot?配置多個JdbcTemplate的實現(xiàn)步驟

    SpringBoot?配置多個JdbcTemplate的實現(xiàn)步驟

    本文介紹了在SpringBoot中配置多個JdbcTemplate的方法,包括創(chuàng)建項目、添加依賴、配置數(shù)據(jù)源和多個JdbcTemplate的使用,感興趣的可以了解一下
    2024-11-11
  • Kotlin 基礎語法詳細介紹

    Kotlin 基礎語法詳細介紹

    這篇文章主要介紹了Kotlin 基礎語法詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 深入淺出MyBatis中映射文件和實體類的關(guān)聯(lián)性

    深入淺出MyBatis中映射文件和實體類的關(guān)聯(lián)性

    這篇文章主要介紹了MyBatis中映射文件和實體類的關(guān)聯(lián)性的相關(guān)知識,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • Java Semaphore信號量使用分析講解

    Java Semaphore信號量使用分析講解

    Semaphore實際上是一種共享鎖,因為它允許多個線程并發(fā)獲取共享的資源,在Semaphore對象創(chuàng)建時必須設置可用令牌的初始數(shù)量permits,用于控制并發(fā)時同時獲取資源權(quán)限的線程數(shù)量,這篇文章主要介紹了Java中的Semaphore如何使用,需要的朋友可以參考下
    2022-12-12
  • 淺析Java中的GC垃圾回收器的意義及與GC的交互

    淺析Java中的GC垃圾回收器的意義及與GC的交互

    這篇文章主要介紹了Java中的GC垃圾回收器的意義及與其的交互,GC是Java虛擬機JVM的一項重要特性,需要的朋友可以參考下
    2015-12-12
  • java數(shù)據(jù)庫連接池的特點及步驟

    java數(shù)據(jù)庫連接池的特點及步驟

    大家好,本篇文章主要講的是數(shù)據(jù)庫連接池的特點及步驟,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • idea以任意順序debug多線程程序的具體用法

    idea以任意順序debug多線程程序的具體用法

    在idea中使用debug可以讓多個線程以任意順序執(zhí)行,接下來通過本文給大家介紹idea以任意順序debug多線程程序的具體用法,需要的朋友參考下吧
    2021-08-08

最新評論

开原市| 合川市| 津南区| 调兵山市| 隆子县| 高安市| 灵山县| 石阡县| 玉树县| 论坛| 闽侯县| 翁源县| 岗巴县| 湛江市| 邵武市| 盘锦市| 托克托县| 新巴尔虎左旗| 新干县| 东至县| 嵊州市| 句容市| 锡林郭勒盟| 堆龙德庆县| 正镶白旗| 广安市| 昌乐县| 密云县| 乌鲁木齐县| 临江市| 赤水市| 湘潭县| 虎林市| 姜堰市| 中宁县| 昆山市| 博乐市| 安吉县| 南充市| 宿迁市| 丰顺县|