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)注明出處。