線程池--基本框架的了解:Executor框架

java中的線程池是通過Executor框架實現(xiàn)的搀突,Executor 框架包括類:Executor,Executors领迈,ExecutorService,ThreadPoolExecutor 留凭,Callable和Future、FutureTask的使用等赌莺。

線程池的框架圖冰抢,如下:


線程池的框架圖.png
核心框架圖

Executor: 所有線程池的接口,只有一個方法。

public interface Executor {        
  void execute(Runnable command);      
}

ExecutorService: 增加Executor的行為艘狭,是Executor實現(xiàn)類的最直接接口挎扰。

public interface ExecutorService extends Executor {

    void shutdown();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;

    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

AbstractExecutorService:是一個抽象類翠订,它實現(xiàn)了ExecutorService接口。

public abstract class AbstractExecutorService implements ExecutorService {

    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { };
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { };
    public Future<?> submit(Runnable task) {};
    public <T> Future<T> submit(Runnable task, T result) { };
    public <T> Future<T> submit(Callable<T> task) { };
    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                            boolean timed, long nanos)
        throws InterruptedException, ExecutionException, TimeoutException {
    };
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
    };
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                           long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
    };
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
    };
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                         long timeout, TimeUnit unit)
        throws InterruptedException {
    };
}

Executors: 提供了一系列工廠方法用于創(chuàng)先線程池遵倦,返回的線程池都實現(xiàn)了ExecutorService 接口尽超。詳細了解

ThreadPoolExecutor:線程池的具體實現(xiàn)類,一般用的各種線程池都是基于這個類實現(xiàn)的。ThreadPoolExecutor繼承了AbstractExecutorService梧躺。詳細了解
構(gòu)造方法如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {

        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);

}

corePoolSize:線程池的核心線程數(shù),線程池中運行的線程數(shù)也永遠不會超過 corePoolSize 個,默認情況下可以一直存活似谁。可以通過設(shè)置allowCoreThreadTimeOut為True,此時 核心線程數(shù)就是0,此時keepAliveTime控制所有線程的超時時間掠哥。
maximumPoolSize:線程池允許的最大線程數(shù);
keepAliveTime: 指的是空閑線程結(jié)束的超時時間;
unit :是一個枚舉巩踏,表示 keepAliveTime 的單位;
workQueue:表示存放任務(wù)的BlockingQueue<Runnable隊列。



線程池的工作過程如下:

  1. 線程池剛創(chuàng)建時续搀,里面沒有一個線程塞琼。任務(wù)隊列是作為參數(shù)傳進來的。不過禁舷,就算隊列里面有任務(wù)彪杉,線程池也不會馬上執(zhí)行它們。
  2. 當(dāng)調(diào)用 execute() 方法添加一個任務(wù)時牵咙,線程池會做如下判斷:
  3. 如果正在運行的線程數(shù)量小于 corePoolSize派近,那么馬上創(chuàng)建線程運行這個任務(wù);
  4. 如果正在運行的線程數(shù)量大于或等于 corePoolSize洁桌,那么將這個任務(wù)放入隊列渴丸;
  5. 如果這時候隊列滿了,而且正在運行的線程數(shù)量小于 maximumPoolSize另凌,那么還是要創(chuàng)建非核心線程立刻運行這個任務(wù)曙强;
  6. 如果隊列滿了,而且正在運行的線程數(shù)量大于或等于 maximumPoolSize途茫,那么線程池會拋出異常RejectExecutionException。
  7. 當(dāng)一個線程完成任務(wù)時溪食,它會從隊列中取下一個任務(wù)來執(zhí)行囊卜。
  8. 當(dāng)一個線程無事可做,超過一定的時間(keepAliveTime)時错沃,線程池會判斷栅组,如果當(dāng)前運行的線程數(shù)大于 corePoolSize,那么這個線程就被停掉枢析。所以線程池的所有任務(wù)完成后玉掸,它最終會收縮到 corePoolSize 的大小。

線程池最常用的提交任務(wù)的方法有兩種:
execute:

ExecutorService.execute(Runnable runable)醒叁;

submit:

FutureTask task = ExecutorService.submit(Runnable runnable);

FutureTask<T> task = ExecutorService.submit(Runnable runnable,T Result);

FutureTask<T> task = ExecutorService.submit(Callable<T> callable);

submit(Callable callable)的實現(xiàn)司浪,submit(Runnable runnable)同理泊业。

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    FutureTask<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

可以看出submit開啟的是有返回結(jié)果的任務(wù),會返回一個FutureTask對象啊易,這樣就能通過get()方法得到結(jié)果吁伺。submit最終調(diào)用的也是execute(Runnable runable),submit只是將Callable對象或Runnable封裝成一個FutureTask對象租谈,因為FutureTask是個Runnable篮奄,所以可以在execute中執(zhí)行。關(guān)于Callable對象和Runnable怎么封裝成FutureTask對象割去,見Callable和Future窟却、FutureTask的使用

參考來自http://blog.csdn.net/he90227/article/details/52576452

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呻逆,一起剝皮案震驚了整個濱河市夸赫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌页慷,老刑警劉巖憔足,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酒繁,居然都是意外死亡滓彰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門州袒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揭绑,“玉大人,你說我怎么就攤上這事郎哭∷耍” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵夸研,是天一觀的道長邦蜜。 經(jīng)常有香客問我,道長亥至,這世上最難降的妖魔是什么悼沈? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮姐扮,結(jié)果婚禮上絮供,老公的妹妹穿的比我還像新娘。我一直安慰自己茶敏,他們只是感情好壤靶,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惊搏,像睡著了一般贮乳。 火紅的嫁衣襯著肌膚如雪忧换。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天塘揣,我揣著相機與錄音包雀,去河邊找鬼。 笑死亲铡,一個胖子當(dāng)著我的面吹牛才写,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奖蔓,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赞草,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吆鹤?” 一聲冷哼從身側(cè)響起厨疙,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疑务,沒想到半個月后沾凄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡知允,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年撒蟀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片温鸽。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡保屯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涤垫,到底是詐尸還是另有隱情姑尺,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布蝠猬,位于F島的核電站切蟋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏榆芦。R本人自食惡果不足惜敦姻,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歧杏。 院中可真熱鬧,春花似錦迷守、人聲如沸犬绒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凯力。三九已至茵瘾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咐鹤,已是汗流浹背拗秘。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留祈惶,地道東北人雕旨。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像捧请,于是被迫代替她去往敵國和親凡涩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 為什么要用線程池 關(guān)于為什么要使用多線程疹蛉,請參考【多線程與并發(fā)】:線程的創(chuàng)建活箕、狀態(tài)、方法中的最后一點可款。 那為什么要...
    maxwellyue閱讀 550評論 0 1
  • 先看幾個概念:線程:進程中負責(zé)程序執(zhí)行的執(zhí)行單元闺鲸。一個進程中至少有一個線程筋讨。多線程:解決多任務(wù)同時執(zhí)行的需求,合理...
    yeying12321閱讀 541評論 0 0
  • 前言:線程是稀缺資源翠拣,如果被無限制的創(chuàng)建版仔,不僅會消耗系統(tǒng)資源,還會降低系統(tǒng)的穩(wěn)定性误墓,合理的使用線程池對線程進行統(tǒng)一...
    SDY_0656閱讀 716評論 0 1
  • 并發(fā)的學(xué)習(xí)與使用系列 第五篇 線程池的技術(shù)背景 在面向?qū)ο缶幊讨新福瑒?chuàng)建和銷毀對象是很費時間的,因為創(chuàng)建一個對象要獲...
    SilenceDut閱讀 1,068評論 1 24
  • 劉紅葉跟著婚車回到了佳偉的家里谜慌,結(jié)婚的流程怎樣進行然想,或者周曉妮和她不停的說的什么,她都沒有走心欣范。她覺得這樣的...
    思想聚焦的原創(chuàng)閱讀 134評論 0 6