Java基礎(chǔ)-并發(fā)編程-線程執(zhí)行器executor

Java工程師知識(shí)樹 / Java基礎(chǔ)


線程實(shí)現(xiàn)方式

Thread挤渐、Runnable疙渣、Callable

//實(shí)現(xiàn)Runnable接口的類將被Thread執(zhí)行,表示一個(gè)基本任務(wù)
public interface Runnable {    
    //run方法就是它所有內(nèi)容谣旁,就是實(shí)際執(zhí)行的任務(wù)    
    public abstract void run();
}
//Callable同樣是任務(wù)阀参,與Runnable接口的區(qū)別在于它接口泛型栋艳,同時(shí)它執(zhí)行任務(wù)候帶有返回值恢准;
//Callable的使用通過外層封裝成Future來使用
public interface Callable<V> {    
    //相對(duì)于run方法蔗包,call方法帶有返回值    
    V call() throws Exception;
}

注意:?jiǎn)?dòng)Thread線程只能用start(JNI方法)來啟動(dòng)秉扑,start方法通知虛擬機(jī),虛擬機(jī)通過調(diào)用器映射到底層操作系統(tǒng)调限,通過操作系統(tǒng)來創(chuàng)建線程來執(zhí)行當(dāng)前任務(wù)的run方法

Executor框架

Executor接口是線程池框架中最基礎(chǔ)的部分舟陆,定義了一個(gè)用于執(zhí)行Runnable的execute方法。從圖中可以看出Exectuor下有一個(gè)重要的子接口ExecutorService旧噪,其中定義了線程池的具體行為:

  • execute(Runnable runnable):執(zhí)行Runnable類型的任務(wù)

  • submit(task):用來提交Callable或者Runnable任務(wù)吨娜,并返回代表此任務(wù)的Future對(duì)象

  • shutdown():在完成已經(jīng)提交的任務(wù)后封閉辦事,不在接管新的任務(wù)

  • shutdownNow():停止所有正在履行的任務(wù)并封閉辦事

  • isTerminated():是一個(gè)鉤子函數(shù)淘钟,測(cè)試是否所有任務(wù)都履行完畢了

  • isShutdown():是一個(gè)鉤子函數(shù)宦赠,測(cè)試是否該ExecutorService是否被關(guān)閉

ExecutorService中的重點(diǎn)屬性:

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;

ctl:對(duì)線程池的運(yùn)行狀態(tài)和線程池中有效線程的數(shù)量進(jìn)行控制的一個(gè)字段,它包含兩部分信息:線程池的運(yùn)行狀態(tài)(runState)和線程池內(nèi)有效線程的數(shù)量(workerCount)米母。

這里可以看到勾扭,使用Integer類型來保存,高3位保存runState铁瞒,低29位保存workerCount妙色。COUNT_BITS 就是29,CAPACITY 就是1左移29位減1(29個(gè)1)慧耍,這個(gè)常量表示workerCount的上限值身辨,大約是5億。

ctl相關(guān)方法:

//獲取運(yùn)行狀態(tài)
private static int runStateOf(int c){ 
    return c & ~CAPACITY; 
}
//獲取活動(dòng)線程數(shù)
private static int workerCountOf(int c)  { 
    return c & CAPACITY; 
}
//獲取運(yùn)行狀態(tài)和活動(dòng)線程數(shù)的值
private static int ctlOf(int rs, int wc) { 
    return rs | wc; 
}

線程池的狀態(tài):

    RUNNING = -1 << COUNT_BITS? //高3位為111
    SHUTDOWN = 0 << COUNT_BITS? //高3位為000
    STOP = 1 << COUNT_BITS? //高3位為001
    TIDYING = 2 << COUNT_BITS? //高3位為010
    TERMINATED = 3 << COUNT_BITS? //高3位為011

線程池實(shí)例的狀態(tài)

1芍碧、RUNNING

  • 狀態(tài)說明:線程池處于RUNNING狀態(tài)煌珊,能夠接收新任務(wù),以及對(duì)已添加的任務(wù)進(jìn)行處理泌豆。
  • 狀態(tài)切換:線程池的初始化狀態(tài)是RUNNING定庵。換句話說,線程池一旦被創(chuàng)建踪危,就處于RUNNING狀態(tài)蔬浙,并且線程池中的任務(wù)數(shù)為0。

2贞远、SHUTDOWN

  • 狀態(tài)說明:線程池處于SHUTDOWN狀態(tài)畴博,不接收新任務(wù),能夠處理已經(jīng)添加的任務(wù)蓝仲。
  • 狀態(tài)切換:調(diào)用shutdown()方法時(shí)俱病,線程池由RUNNING -> SHUTDOWN蜜唾。

3、STOP

  • 狀態(tài)說明:線程池處于STOP狀態(tài)庶艾,不接收新任務(wù)袁余,不處理已提交的任務(wù),并且會(huì)中斷正在處理的任務(wù)咱揍。
  • 狀態(tài)切換:調(diào)用線程池中的shutdownNow()方法時(shí)颖榜,線程池由(RUNNING or SHUTDOWN) -> STOP。

4煤裙、TIDYING

  • 狀態(tài)說明:當(dāng)所有的任務(wù)已經(jīng)停止掩完,ctl記錄“任務(wù)數(shù)量”為0,線程池會(huì)變?yōu)門IDYING狀態(tài)硼砰。當(dāng)線程池處于TIDYING狀態(tài)時(shí)且蓬,會(huì)執(zhí)行鉤子函數(shù) terminated()。terminated()在ThreadPoolExecutor類中是空题翰, 的恶阴,若用戶想在線程池變?yōu)門IDYING時(shí),進(jìn)行相應(yīng)處理豹障,可以通過重載 terminated()函數(shù)來實(shí)現(xiàn)冯事。
  • 狀態(tài)切換:當(dāng)線程池在SHUTDOWN狀態(tài)下,阻塞隊(duì)列為空并且線程池中執(zhí)行任務(wù)也為空時(shí)血公,就會(huì)由SHUTDOWN -> TIDYING昵仅。當(dāng)線程池在STOP狀態(tài)下,線程池中執(zhí)行的任務(wù)為空時(shí)累魔,就會(huì)由STOP-> TIDYING摔笤。

5、TERMINATED

  • 狀態(tài)說明:線程池線程池徹底停止垦写,線程池處于TERMINATED狀態(tài)吕世,
  • 狀態(tài)切換:線程池處于TIDYING狀態(tài)時(shí),執(zhí)行完terminated()之后梯澜, 就會(huì)由TIDYING->TERMINATED寞冯。

線程池使用

線程池使用

ThreadPoolExecutor構(gòu)造方法

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;
}

任務(wù)的提交流程

執(zhí)行圖:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渴析,一起剝皮案震驚了整個(gè)濱河市晚伙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俭茧,老刑警劉巖咆疗,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異母债,居然都是意外死亡午磁,警方通過查閱死者的電腦和手機(jī)尝抖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迅皇,“玉大人昧辽,你說我怎么就攤上這事〉峭牵” “怎么了搅荞?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)框咙。 經(jīng)常有香客問我咕痛,道長(zhǎng),這世上最難降的妖魔是什么喇嘱? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任茉贡,我火速辦了婚禮,結(jié)果婚禮上者铜,老公的妹妹穿的比我還像新娘腔丧。我一直安慰自己,他們只是感情好作烟,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布悔据。 她就那樣靜靜地躺著,像睡著了一般俗壹。 火紅的嫁衣襯著肌膚如雪科汗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天绷雏,我揣著相機(jī)與錄音头滔,去河邊找鬼。 笑死涎显,一個(gè)胖子當(dāng)著我的面吹牛坤检,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播期吓,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼早歇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了讨勤?” 一聲冷哼從身側(cè)響起箭跳,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎潭千,沒想到半個(gè)月后谱姓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刨晴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年屉来,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了路翻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茄靠,死狀恐怖茂契,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慨绳,我是刑警寧澤账嚎,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站儡蔓,受9級(jí)特大地震影響郭蕉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喂江,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一召锈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧获询,春花似錦涨岁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至尝哆,卻和暖如春秉撇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秋泄。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工琐馆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恒序。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓瘦麸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親歧胁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滋饲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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