線程池

1:ThreadPoolExecutor 創(chuàng)建基本線程池

創(chuàng)建線程池,主要是利用ThreadPoolExecutor這個(gè)類(lèi),而這個(gè)類(lèi)有幾種構(gòu)造方法,其中參數(shù)最多的一種構(gòu)造方法如下:

publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnit unit,BlockingQueue<Runnable>workQueue,ThreadFactory threadFactory){...}

corePoolSize: 該線程池中核心線程的數(shù)量。

注意:線程池中存在核心線程與非核心線程,核心線程一旦創(chuàng)建會(huì)一直執(zhí)行任務(wù)或等待任務(wù)到來(lái),而非核心線程只在任務(wù)隊(duì)列塞滿任務(wù)時(shí)去執(zhí)行多出的任務(wù),并且非核心線程在等待一段時(shí)間后將會(huì)被回收,這個(gè)時(shí)間作為參數(shù)可調(diào)配,見(jiàn)下面的keepAliveTime參數(shù)。

maximumPoolSize:該線程池中最大線程數(shù)量。(區(qū)別于corePoolSize)

keepAliveTime:從字面上就可以理解,是非核心線程空閑時(shí)要等待下一個(gè)任務(wù)到來(lái)的時(shí)間,當(dāng)任務(wù)很多,每個(gè)任務(wù)執(zhí)行時(shí)間很短的情況下調(diào)大該值有助于提高線程利用率。注意:當(dāng)allowCoreThreadTimeOut屬性設(shè)為true時(shí),該屬性也可用于核心線程。

unit:上面時(shí)間屬性的單位

workQueue:任務(wù)隊(duì)列,后面詳述。

threadFactory:線程工廠,可用于設(shè)置線程名字等等,一般無(wú)須設(shè)置該參數(shù)。

設(shè)置好幾個(gè)參數(shù)就可以創(chuàng)建一個(gè)基本的線程池,而之后的各種線程池都是在這種基本線程池的基礎(chǔ)上延伸的。

//創(chuàng)建基本線程池finalThreadPoolExecutor threadPoolExecutor=newThreadPoolExecutor(3,5,1,TimeUnit.SECONDS,newLinkedBlockingQueue<Runnable>(100));

具體過(guò)程:

1.execute一個(gè)線程之后,如果線程池中的線程數(shù)未達(dá)到核心線程數(shù),則會(huì)立馬啟用一個(gè)核心線程去執(zhí)行。

2.execute一個(gè)線程之后,如果線程池中的線程數(shù)已經(jīng)達(dá)到核心線程數(shù),且workQueue未滿,則將新任務(wù)放入workQueue中等待執(zhí)行。

3.execute一個(gè)線程之后,如果線程池中的線程數(shù)已經(jīng)達(dá)到核心線程數(shù)但未超過(guò)非核心線程數(shù),且workQueue已滿,則開(kāi)啟一個(gè)非核心線程來(lái)執(zhí)行任務(wù)。

4.execute一個(gè)線程之后,如果線程池中的線程數(shù)已經(jīng)超過(guò)非核心線程數(shù),則拒絕執(zhí)行該任務(wù),采取飽和策略,并拋出RejectedExecutionException異常。

2:FixedThreadPool (可重用固定線程數(shù))

Executors類(lèi)中的創(chuàng)建方法:

FixedThreadPool創(chuàng)建

特點(diǎn):參數(shù)為核心線程數(shù),只有核心線程,無(wú)非核心線程,并且阻塞隊(duì)列無(wú)界。

demo代碼:

創(chuàng)建:

//創(chuàng)建fixed線程池finalExecutorService fixedThreadPool=Executors.newFixedThreadPool(5);

使用:

/**

? ? * fixed線程池

? ? */mFixedPoolThread.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){for(inti=0;i<30;i++){finalintfinali=i;Runnablerunnable=newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(2000);Log.d("Thread","run: "+finali);Log.d("當(dāng)前線程:",Thread.currentThread().getName());}catch(InterruptedExceptione){e.printStackTrace();}}};fixedThreadPool.execute(runnable);}}});

結(jié)果為每2s打印5次任務(wù),跟上面的基礎(chǔ)線程池類(lèi)似。

3:CachedThreadPool (按需創(chuàng)建)

Executors類(lèi)中的創(chuàng)建方法:

CachedThreadPool創(chuàng)建

特點(diǎn):沒(méi)有核心線程,只有非核心線程,并且每個(gè)非核心線程空閑等待的時(shí)間為60s,采用SynchronousQueue隊(duì)列。

demo代碼:

創(chuàng)建:

//創(chuàng)建Cached線程池finalExecutorService cachedThreadPool=Executors.newCachedThreadPool();

使用:

/**

? ? * cached線程池

? ? */mCachedPoolThread.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){for(inti=0;i<30;i++){finalintfinali=i;Runnablerunnable=newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(2000);Log.d("Thread","run: "+finali);}catch(InterruptedExceptione){e.printStackTrace();}}};cachedThreadPool.execute(runnable);}}});

結(jié)果:過(guò)2s后直接打印30個(gè)任務(wù)

結(jié)果分析:

因?yàn)闆](méi)有核心線程,其他全為非核心線程,SynchronousQueue是不存儲(chǔ)元素的,每次插入操作必須伴隨一個(gè)移除操作,一個(gè)移除操作也要伴隨一個(gè)插入操作。

當(dāng)一個(gè)任務(wù)執(zhí)行時(shí),先用SynchronousQueue的offer提交任務(wù),如果線程池中有線程空閑,則調(diào)用SynchronousQueue的poll方法來(lái)移除任務(wù)并交給線程處理;如果沒(méi)有線程空閑,則開(kāi)啟一個(gè)新的非核心線程來(lái)處理任務(wù)。

由于maximumPoolSize是無(wú)界的,所以如果線程處理任務(wù)速度小于提交任務(wù)的速度,則會(huì)不斷地創(chuàng)建新的線程,這時(shí)需要注意不要過(guò)度創(chuàng)建,應(yīng)采取措施調(diào)整雙方速度,不然線程創(chuàng)建太多會(huì)影響性能。

從其特點(diǎn)可以看出,CachedThreadPool適用于有大量需要立即執(zhí)行的耗時(shí)少的任務(wù)的情況。

4:SingleThreadPool(單個(gè)核線的fixed)

創(chuàng)建方法:

SingleThreadPool創(chuàng)建

創(chuàng)建:

//創(chuàng)建Single線程池finalExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();

使用:

/**

? ? * single線程池

? ? */mSinglePoolExecute.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){for(inti=0;i<30;i++){finalintfinali=i;xRunnablerunnable=newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(2000);Log.d("Thread","run: "+finali);}catch(InterruptedExceptione){e.printStackTrace();}}};singleThreadExecutor.execute(runnable);}}});

結(jié)果:每2s打印一個(gè)任務(wù),由于只有一個(gè)核心線程,當(dāng)被占用時(shí),其他的任務(wù)需要進(jìn)入隊(duì)列等待。

5:ScheduledThreadPool(定時(shí)延時(shí)執(zhí)行)

創(chuàng)建方法:

ScheduledThreadPool創(chuàng)建1

ScheduledThreadPool創(chuàng)建2

創(chuàng)建:

//創(chuàng)建Scheduled線程池finalScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(3);

使用:

/**

? ? * scheduled線程池

? ? */mScheduledTheadPool.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){Runnablerunnable=newRunnable(){@Overridepublicvoidrun(){Log.d("Thread","This task is delayed to execute");}};scheduledThreadPool.schedule(runnable,10,TimeUnit.SECONDS);//延遲啟動(dòng)任務(wù)//延遲5s后啟動(dòng),每1s執(zhí)行一次? ? ? ? ? ? scheduledThreadPool.scheduleAtFixedRate(runnable,5,1,TimeUnit.SECONDS);//啟動(dòng)后第一次延遲5s執(zhí)行,后面延遲1s執(zhí)行? scheduledThreadPool.scheduleWithFixedDelay(runnable,5,1,TimeUnit.SECONDS);}});

線程池其它方法:

1.shutDown()關(guān)閉線程池,不影響已經(jīng)提交的任務(wù)

2.shutDownNow()關(guān)閉線程池,并嘗試去終止正在執(zhí)行的線程

3.allowCoreThreadTimeOut(boolean value)允許核心線程閑置超時(shí)時(shí)被回收

4.submit 一般情況下我們使用execute來(lái)提交任務(wù),但是有時(shí)候可能也會(huì)用到submit,使用submit的好處是submit有返回值。

5.beforeExecute()- 任務(wù)執(zhí)行前執(zhí)行的方法

6.afterExecute()-任務(wù)執(zhí)行結(jié)束后執(zhí)行的方法

7.terminated()-線程池關(guān)閉后執(zhí)行的方法

作者:無(wú)問(wèn)o

鏈接:http://www.itdecent.cn/p/7b2da1d94b42

來(lái)源:簡(jiǎn)書(shū)

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

結(jié)果如代碼所述。

作者:無(wú)問(wèn)o

鏈接:http://www.itdecent.cn/p/7b2da1d94b42

來(lái)源:簡(jiǎn)書(shū)

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

作者:無(wú)問(wèn)o

鏈接:http://www.itdecent.cn/p/7b2da1d94b42

來(lái)源:簡(jiǎn)書(shū)

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

作者:無(wú)問(wèn)o

鏈接:http://www.itdecent.cn/p/7b2da1d94b42

來(lái)源:簡(jiǎn)書(shū)

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、前言 ??如果我們平時(shí)接觸過(guò)多線程開(kāi)發(fā),那肯定對(duì)線程池不陌生。在我們?cè)鹊膶W(xué)習(xí)中,我們了解到,如果我們需要?jiǎng)?chuàng)建...
    騎著烏龜去看海閱讀 461評(píng)論 0 4
  • 不同形式的線程雖然都是線程,但是它們?nèi)匀痪哂胁煌奶匦院蛯?shí)用場(chǎng)景: AsyncTask封裝了線程池和Handler...
    胡二囧閱讀 1,206評(píng)論 0 4
  • 除了Thread,Android中扮演線程的角色還有:AsyncTask、HandlerThread、Intent...
    胡飛洋閱讀 288評(píng)論 0 0
  • 表情是什么,我認(rèn)為表情就是表現(xiàn)出來(lái)的情緒。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了,難過(guò)就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,456評(píng)論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者,不喜歡去冒險(xiǎn),但是人生放棄了冒險(xiǎn),也就放棄了無(wú)數(shù)的可能。 ...
    yichen大刀閱讀 7,580評(píng)論 0 4

友情鏈接更多精彩內(nèi)容