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

Java 線程池全面總結與詳解

 更新時間:2021年10月29日 09:41:36   作者:該用戶快成仙了  
在一個應用程序中,我們需要多次使用線程,也就意味著,我們需要多次創(chuàng)建并銷毀線程。而創(chuàng)建并銷毀線程的過程勢必會消耗內存。而在Java中,內存資源是及其寶貴的,所以,我們就提出了線程池的概念

線程池是很常用的并發(fā)框架,幾乎所有需要異步和并發(fā)處理任務的程序都可用到線程池。
使用線程池的好處如下:

  • 降低資源消耗:可重復利用已創(chuàng)建的線程池,降低創(chuàng)建和銷毀帶來的消耗;
  • 提高響應速度:任務到達時,可立即執(zhí)行,無需等待線程創(chuàng)建;
  • 提高線程的可管理性:線程池可對線程統(tǒng)一分配、調優(yōu)和監(jiān)控。

原理

線程池的原理非常簡單,這里用處理流程來概括:

  • 線程池判斷核心池里的線程是否都在執(zhí)行任務,如果不是,創(chuàng)建一個新的線程來執(zhí)行任務;
  • 如果核心線程池已滿,則將新任務存在工作隊列中;
  • 如果工作隊列滿了,線程數(shù)量沒有達到線程池上限的前提下,新建一個線程來執(zhí)行任務;
  • 線程數(shù)量達到上限,則觸發(fā)飽和策略來處理這個任務;

使用工作隊列,是為了盡可能降低線程創(chuàng)建的開銷。工作隊列用阻塞隊列來實現(xiàn)。

阻塞隊列

阻塞隊列(BlockingQueue)是指支持阻塞的插入和移除元素的隊列。

  • 阻塞的插入:當隊列滿時,阻塞插入元素的線程,直到隊列不滿;
  • 阻塞的移除:當隊列為空,阻塞移除元素的線程,直到隊列不為空;

原理:使用通知者模式實現(xiàn)。當生產(chǎn)者往滿的隊列中添加元素時,會阻塞生產(chǎn)者。消費者移除元素時,會通知生產(chǎn)者當前隊列可用。

阻塞隊列有以下三種類型,分別是:

  • 有界阻塞隊列:ArrayBlockingQueue(數(shù)組),LinkedBlockingQueue(鏈表)
  • 無界阻塞隊列:LinkedTransferQueue(鏈表),PriorityBlockingQueue(支持優(yōu)先級排序),DelayQueue(支持延時獲取元素的無界阻塞隊列)
  • 同步移交隊列:SynchronousQueue

有界阻塞隊列

主要包括ArrayBlockingQueue(數(shù)組),LinkedBlockingQueue(鏈表)兩種。有界隊列大小與線程數(shù)量大小相互配合,隊列容量大線程數(shù)量小時,可減少上下文切換降低cpu使用率,但是會降低吞吐量。

無界阻塞隊列

比較常用的是LinkedTransferQueue。FixedThreadPool就是用這個實現(xiàn)的。無界阻塞隊列要慎重使用,因為在某些情況,可能會導致大量的任務堆積到隊列中,導致內存飆升。

同步移交隊列

SynchronousQueue。不存儲元素的阻塞隊列,每一個put操作必須等待一個take操作,否則不能繼續(xù)添加元素。用于實現(xiàn)CachedThreadPool線程池。

各個線程池所使用的任務隊列映射關系如下:

線程池阻塞隊列

FixedThreadPoolLinkedBlockingQueueSingleThreadExecutorLinkedBlockingQueueCachedThreadExecutorSynchronousQueueScheduledThreadPoolExecutorLinkedBlockingQueue

實現(xiàn)類分析

ThreadPoolExecutor是Java線程池的實現(xiàn)類,是Executor接口派生出來的最核心的類。依賴關系圖如下:

深入淺出談Java線程池原理及分析

這里不得不提到Executor框架,該框架包含三大部分,如下:

  • 任務。被執(zhí)行任務需要實現(xiàn)的接口:Runnable和Callable;
  • 任務執(zhí)行。即上述核心接口Executor以及繼承而來的ExecutorService。ExecutorService派生出如下兩個類:ThreadPoolExecutor:線程池核心實現(xiàn)類;ScheduledThreadPoolExecutor:用來做定時任務;
  • 異步計算的結果。接口Future和實現(xiàn)Future接口的FutureTask類。線程池創(chuàng)建
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds, runnableTaskQueue, handler)

構造方法如下:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

參數(shù)說明:

  • corePoolSize:核心池的線程數(shù)量;
  • workQueue:用于保存任務的工作隊列;
  • maximumPoolSize:最大線程池的大??;
  • keepAliveTime:當線程數(shù)量大于核心池線程數(shù)量時,keepAliveTime為多余的空閑線程等待新任務的最長時間,超過這個時間,多余的線程會被終止;
  • TimeUnit:keepAliveTime的單位;
  • ThreadFactory:線程工廠,可以給線程設置名字;
  • handler:飽和策略。當隊列和線程池都滿了,會觸發(fā)飽和策略,來處理新提交的任務。飽和策略以下幾種:AbortPolicy:直接拋出異常;CallerRunsPolicy:只用調用者所在線程來運行任務;DiscardOldestPolicy:丟棄最近一個任務并執(zhí)行當前任務;DiscardPolicy:不處理,丟棄掉。

使用Executors創(chuàng)建線程池

使用工具類Executors可創(chuàng)建三種類型的線程池:FixedThreadPool、SingleThreadExecutor、CachedThreadPool。本質上也是調用上述構造方法。理解了前文的參數(shù)解釋,下面三種線程池也就容易理解了。

FixedThreadPool

可重用固定線程數(shù)的線程池。

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

工作流程如下:

  • 如果當前運行的線程數(shù)少于corePoolSize,則創(chuàng)建新線程來執(zhí)行任務;
  • 線程數(shù)等于corePoolSize之后,新任務加入LinkedBlockingQueue(無界阻塞隊列)。因為最大線程數(shù)maximumPoolSize參數(shù)值等于corePoolSize,不會產(chǎn)生多余線程;
  • 線程執(zhí)行完任務之后會反復從LinkedBlockingQueue中獲取任務來執(zhí)行。

SingleThreadExecutor

單個worker線程的線程池

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

SingleThreadExecutor與FixedThreadPool的區(qū)別在于,maximumPoolSize和corePoolSize都設置成了1,其它參數(shù)都一樣。

  • CachedThreadPool
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

CachedThreadPool將corePoolSize設置為0,maximumPoolSize設置為無限大,同時使用了一個沒有容量的工作隊列SynchronousQueue。這個線程池沒有固定的核心線程,而是根據(jù)需要創(chuàng)建新線程。

工作流程:

  • 有新任務時,主線程執(zhí)行SynchronousQueue.offer操作,空閑線程執(zhí)行SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS)操作,配對成功則將任務交給空閑線程執(zhí)行;
  • 當沒有空閑線程時,上面的配對操作失敗,此時會創(chuàng)建一個新線程來執(zhí)行任務;
  • 任務執(zhí)行完畢后,空閑線程會等待60秒。60秒內如果有新任務,就立即執(zhí)行,否則時間一過線程就終止。

線程池關閉

調用shutdown或者shutdownNow方法可關閉線程池。原理是遍歷線程池中所有工作線程,調用interrupt方法來中斷線程。

  • shutdown:將線程置為SHUTDOWN狀態(tài),不能接受新的任務,等待所有任務執(zhí)行完畢;
  • shutdownNow:將線程置為STOP狀態(tài),不能接受新的任務,嘗試去終止正在執(zhí)行的惡任務;

這里涉及到ThreadPoolExecutor中定義的線程的五種狀態(tài)

// 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;
  • RUNNING:接受新任務,處理任務;
  • SHUTDOWN:不接受新任務,但會把隊列中任務處理完;
  • STOP:不接受新任務,不處理隊列中的任務,并且終止正在處理的任務;
  • TIDYING:正在執(zhí)行的任務和隊列都為空,進入該狀態(tài),將要執(zhí)行terminated();
  • TERMINATED:所有terminated()方法執(zhí)行完畢,線程池徹底終止。

當隊列和正在執(zhí)行的任務都為空時,由SHUTDOWN轉化為TIDYING;當正在執(zhí)行的任務為空,由STOP轉化為TIDYING。

本博客從線程池的原理介紹作為切入點,分析了線程池中尤為關鍵的組件:阻塞隊列。同時分析了線程池的核心實現(xiàn)類ThreadPoolExecutor。以線程池的創(chuàng)建和關閉的思路,梳理了相關知識點,包括三種常用線程池介紹以及線程池五種狀態(tài)。

到此這篇關于Java 線程池全面總結與詳解的文章就介紹到這了,更多相關Java 線程池內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 深入探究SpringBoot中的Sleuth用法

    深入探究SpringBoot中的Sleuth用法

    Sleuth是一個分布式跟蹤系統(tǒng),用于跟蹤應用程序中的請求和操作,在本文中,我們將探討SpringBoot中的Sleuth是什么,以及如何使用它來跟蹤應用程序中的請求和操作,感興趣的小伙伴跟著小編一起來探討吧
    2023-07-07
  • java 中DH的方式實現(xiàn)非對稱加密的實例

    java 中DH的方式實現(xiàn)非對稱加密的實例

    這篇文章主要介紹了java 中DH的方式實現(xiàn)非對稱加密的實例的相關資料,這里提供實現(xiàn)簡單實例,需要的朋友可以參考下
    2017-08-08
  • Java難點解讀之異或運算舉例詳解

    Java難點解讀之異或運算舉例詳解

    這篇文章主要介紹了Java難點解讀之異或運算的相關資料,Java中的異或運算是一種位運算符,用于對兩個整數(shù)的每一位進行比較并執(zhí)行異或操作,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-04-04
  • java+jdbc+mysql+socket搭建局域網(wǎng)聊天室

    java+jdbc+mysql+socket搭建局域網(wǎng)聊天室

    這篇文章主要為大家詳細介紹了java+jdbc+mysql+socket搭建局域網(wǎng)聊天室,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • java 非常好用的反射框架Reflections介紹

    java 非常好用的反射框架Reflections介紹

    這篇文章主要介紹了java 反射框架Reflections的使用,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Java工作隊列代碼詳解

    Java工作隊列代碼詳解

    這篇文章主要介紹了Java工作隊列代碼詳解,涉及Round-robin 轉發(fā),消息應答(messageacknowledgments),消息持久化(Messagedurability)等相關內容,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • java向下轉型基礎知識點及實例

    java向下轉型基礎知識點及實例

    在本篇文章里小編給大家整理的是一篇關于java向下轉型基礎知識點及實例內容,有興趣的朋友們可以學習下。
    2021-05-05
  • Java開發(fā)環(huán)境配置教程(win7 64bit)

    Java開發(fā)環(huán)境配置教程(win7 64bit)

    這篇文章主要為大家詳細介紹了win7 64bit下Java開發(fā)環(huán)境的配置教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 使用springboot防止反編譯proguard+xjar

    使用springboot防止反編譯proguard+xjar

    介紹了三種代碼混淆和加密工具的使用方法:ProGuard、Xjar和ClassFinal,ProGuard用于混淆Java字節(jié)碼,Xjar提供對JAR包內資源的加密和動態(tài)解密,而ClassFinal則支持直接加密JAR包或WAR包,通過預研和實際操作
    2024-11-11
  • springboot配置多數(shù)據(jù)源的一款框架(dynamic-datasource-spring-boot-starter)

    springboot配置多數(shù)據(jù)源的一款框架(dynamic-datasource-spring-boot-starter

    dynamic-datasource-spring-boot-starter 是一個基于 springboot 的快速集成多數(shù)據(jù)源的啟動器,今天通過本文給大家分享這款框架配置springboot多數(shù)據(jù)源的方法,一起看看吧
    2021-09-09

最新評論

承德县| 武乡县| 盱眙县| 辉南县| 府谷县| 桃园市| 买车| 文成县| 商城县| 石泉县| 左贡县| 东兴市| 密山市| 白水县| 合江县| 始兴县| 卢氏县| 农安县| 洛南县| 崇义县| 东宁县| 苍梧县| 体育| 兴宁市| 杨浦区| 江口县| 锦州市| 武宣县| 玉田县| 崇阳县| 岚皋县| 旅游| 自贡市| 辉南县| 泰顺县| 平江县| 贵阳市| 巴塘县| 浪卡子县| 神池县| 鹤岗市|