除了Thread外,在Android中扮演線程的角色還有很多,比如AsyncTask和IntentService,同時(shí)HandlerThread也是一種特殊的線程肄满。
盡管AsyncTask和IntentService以及HandlerThread的表現(xiàn)形式有區(qū)別于傳統(tǒng)的線程,但是本質(zhì)上仍然是傳統(tǒng)的線程质涛。
AsyncTask
AsyncTask是一種輕量級(jí)的異步任務(wù)類稠歉,它可以在線程池中執(zhí)行后臺(tái)任務(wù),并把執(zhí)行進(jìn)度和最終結(jié)果傳遞到主線程并在主線程中更新UI汇陆。
AsyncTask封裝了Thread和Handler怒炸。
AsyncTask并不適合特別耗時(shí)的后臺(tái)任務(wù),對(duì)于特別耗時(shí)的后臺(tái)任務(wù)毡代,建議交給線程池阅羹。
- AsyncTask的類聲明
/**
*@Params 參數(shù)類型
*@Progress 后臺(tái)任務(wù)的執(zhí)行進(jìn)度類型
*@Result 后臺(tái)任務(wù)的返回結(jié)果的類型
public abstract class AsyncTask<Params,Progress,Result>
AsyncTask提供了4個(gè)核心方法,他們的含義如下:
- onPreExecute() 在主線程中執(zhí)行教寂,在異步任務(wù)執(zhí)行前被調(diào)用捏鱼,一般可以用于做一些準(zhǔn)備工作。
- doInBackground(Params...params) 在線程池中執(zhí)行酪耕,此方法用于執(zhí)行異步任務(wù) 导梆,params參數(shù)表示異步任務(wù)輸入的參數(shù)。在此方法中可以通過publicProgress方法來更新任務(wù)的進(jìn)度迂烁,publicProgress方法會(huì)調(diào)用onPublicUpdate方法卫键。另外此方法需要返回計(jì)算機(jī)過給onPostExecute方法。
- onProgressUpdate(Progress...values)在主線程中執(zhí)行辅甥,當(dāng)后臺(tái)任務(wù)的執(zhí)行進(jìn)度放生改變時(shí)被調(diào)用洗做。
- onPostExecute(Result...result)在主線程中執(zhí)行,在異步任務(wù)執(zhí)行之后址芯,此方法會(huì)被調(diào)用灾茁,其中result是后臺(tái)任務(wù)被取消時(shí)調(diào)用。這個(gè)時(shí)候onPostExecute()不會(huì)被調(diào)用
除了上述的四個(gè)方法外谷炸,AsyncTask還提供onCancelled()方法北专,它同樣在主線程中執(zhí)行,當(dāng)異步任務(wù)被取消時(shí)調(diào)用旬陡。這個(gè)時(shí)候onPostExecute()不會(huì)被調(diào)用拓颓。
- 示例
private class DownloadFilesTask extends AsyncTask<URL,Interger,Long>{
protected Long doInBackground(URL...urls){
int count = urls.length;
long totalSize = 0;
for (int i=0;i<count;i++){
totalSize += DownLoader.downloadFile(urls[i]);
publishProgress((int)(i/(float)count*100));
// Escape early if cancel() is called
if (isCancelled()){
break;
}
}
return totalSize;
}
protected void onProgressUpdate(Interger... progress){
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result){
showDialog("Download"+result+"bytes");
}
}
- 使用限制
- AsyncTask的類必須在主線程中加載。
- AsyncTask的對(duì)象必須在主線程中加載描孟。
- execute必須在UI線程中調(diào)用驶睦。
- 不要在程序中直接調(diào)用onPreExecute()砰左,onPostExecute,doInBackground()和onProgressUpdate方法场航。
- 一個(gè)AsyncTask對(duì)象只能執(zhí)行一次缠导,即只能調(diào)用一次execute方法,否則回報(bào)異常溉痢。
- 從Android3.0開始僻造,為避免AsyncTask所帶來的并發(fā)錯(cuò)誤,AsyncTask又采用一個(gè)線程來執(zhí)行任務(wù)孩饼。盡管如此髓削,Android3.0的后續(xù)版本,我們?nèi)钥梢酝ㄟ^AsyncTask的executeOnExecutor方法來并行執(zhí)行任務(wù)镀娶。
AsyncTask的工作原理
- execute方法
public final AsyncTask<Params,Progress,Result> execute(Params... params){
return executeExecutor(sDefaultExecutor,params);
}
public final AsyncTask<Params,Progress,Result> executeOnExecutor(Executor exec, Params... params){
if(mStatus!=Status.PENDING) {
switch(mStatus){
case RUNNING:
throw new IllegalStateException("Cannot execute task:"+"the task is already running");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"+"the task has already been executed"+"(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
sDefaultExecutor實(shí)際是一個(gè)串行的線程池立膛,一個(gè)進(jìn)程中所有的AsyncTask全部在這個(gè)串行的線程池中執(zhí)行。
- 線程池執(zhí)行
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
private static class SerialExecutor implements Executor{
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchroized void execute (final Runnable r){
mTasks.offer(new Runnable(){
public void run(){
try{
r.run();
}finally{
scheduleNext();
}
}
});
if(mActive==null){
scheduleNext();
}
}
protected synchroized void scheduleNext(){
if((mActive==mTasks.poll())!=null){
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
首先系統(tǒng)會(huì)把AsyncTask的Params參數(shù)封裝FutureTask對(duì)象汽畴,F(xiàn)utureTask是一個(gè)并發(fā)類旧巾,在這個(gè)它充當(dāng)Runnable的作用。
接著FutureTask會(huì)交給SerialExecutor的execute去處理忍些,SerialExecutor的execute方法首先會(huì)把FutureTask對(duì)象插入到任務(wù)隊(duì)列mTasks中鲁猩,如果這時(shí)候沒有正在活動(dòng)的AsyncTask任務(wù),那么就會(huì)調(diào)用SerialExcutor的scheduleNext方法來執(zhí)行下一個(gè)AsyncTask任務(wù)罢坝。
同時(shí)當(dāng)一個(gè)AsyncTask執(zhí)行完之后廓握,AsyncTask會(huì)繼續(xù)執(zhí)行其他任務(wù)直到所有任務(wù)都被執(zhí)行為止,從這一點(diǎn)可以看出嘁酿,默認(rèn)情況下AsyncTask是串行執(zhí)行隙券。
AsyncTask有兩個(gè)線程池(SerialExcutor和THREAD_POOL_EXECUTOR)和一個(gè)Handler(IntentHandler)
SerialExecutor用于任務(wù)排隊(duì),THREAD_POOL_EXECUTOR
用于真正的執(zhí)行任務(wù)闹司。
IntentHandler用于將執(zhí)行環(huán)境從線程池切換到主線程娱仔。
AsyncTask的構(gòu)造方法中如下一段代碼,由于FutureTask的run方法會(huì)調(diào)用mWorker的call方法游桩,因此mWorker的call方法最終會(huì)在線程池中執(zhí)行牲迫。
mWorker = new WorkerRunnable<Params,Result>(){
public Result call() throws Exception{
mTaskInvoked.set(true);
Process.setThreadPriority(Progress.THREAD_PRIORITY_BACKGROUND);
// noinspection unchecked
return postResult(doInBackground(mParams));
}
};
在mWorker的call方法中,首先將mTaskInvoked設(shè)為true借卧,表示當(dāng)前任務(wù)已經(jīng)被調(diào)用過了盹憎,然后執(zhí)行AsyncTask的doInBackground方法,接著將其返回值傳遞給postResult方法铐刘。
private Result postResult(Result result){
@SuppressWarnings("unchecked)
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,new AsyncTaskResult<Result>(this,result));
message.sendToTarget();
return result;
}
postResult方法會(huì)通過sHandler發(fā)送一個(gè)MESSAGE_POST_RESULT的消息陪每,這個(gè)sHandler定義如下:
private static final InternalHandler sHandler = new InternalHandler();
private static class InteralHandler extends Handler{
@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg){
AsyncTaskResult result = (AsyncTaskResult)msg.obj;
switch(msg.what){
case MESSAGE_POST_RESULT:
//Thread is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
sHandler會(huì)一個(gè)靜態(tài)的Handler對(duì)象,為了能夠?qū)?zhí)行環(huán)境切換到主線程,這就要求sHandler這個(gè)對(duì)象必須在主線程中創(chuàng)建檩禾。由于靜態(tài)成員會(huì)在加載類的時(shí)候進(jìn)行初始化挂签,因此變相要求AsyncTask的類必須在主線程中加載,否則同一線程中的AsyncTask都無法工作盼产。sHandler收到MESSAGE_POST_RESULT這個(gè)消息后回調(diào)AsyncTask的finish方法竹握。
private void finish(Result result){
if(isCancelled){
onCancelled(result);
}else{
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
如果AsyncTask被取消了被調(diào)用onCancelled方法,否則就調(diào)用onPostExecute方法辆飘,可以看出doInBackground中的result會(huì)傳遞給onPostExecute方法。
如果要并行執(zhí)行谓传,要使用executeOnExcutor方法蜈项。
HandlerThread
HandlerThread繼承了Thread,是一種可以使用Handler的Thread续挟,它的實(shí)現(xiàn)也很簡單紧卒,就是在run方法中通過Looper.prepare
創(chuàng)建消息隊(duì)列,并通過Looper.loop來開啟消息循環(huán)诗祸,這樣在實(shí)際中就允許在HandlerThread中創(chuàng)建Handler了跑芳,HandlerThread的run方法如下所示:
public void run(){
mTid = Progress.myTid();
Looper.prepare();
synchroized(this){
mLooper = Looper.myLooper();
notifyAll();
}
Progress.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
HnadlerThread在內(nèi)部創(chuàng)建了一個(gè)消息隊(duì)列,外部需要通過Handler的消息方式來通知HandlerThread執(zhí)行一個(gè)具體任務(wù)直颅。
HandlerThread的run是一個(gè)無限循環(huán)博个,因此當(dāng)明確不需要時(shí)通過它的quit或者quitSafely方法終止線程運(yùn)行。
一個(gè)具體的應(yīng)用場景就是IntentService功偿。
IntentService
IntentService是一種特殊的Service盆佣,它繼承Service并且它是一個(gè)抽象類,因此創(chuàng)建它的子類才能使用IntentService械荷。
IntentService可用于執(zhí)行后臺(tái)耗時(shí)任務(wù)共耍,當(dāng)任務(wù)執(zhí)行后它會(huì)自動(dòng)停止,同時(shí)由于IntentService是服務(wù)的原因吨瞎,導(dǎo)致它的優(yōu)先級(jí)比單純的線程要高很多痹兜,所以IntentService適合執(zhí)行一些高優(yōu)先級(jí)的后臺(tái)任務(wù)。
IntentService封裝了HandlerThread和Handler颤诀。
- onCreate
public void onCreate(){
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService["+mName+"]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceHandler);
}
當(dāng)IntentService被第一次啟動(dòng)時(shí)字旭,它的onCreate方法會(huì)被調(diào)用,onCreate方法會(huì)創(chuàng)建一個(gè)HandlerThread着绊,然后使用它的Looper來構(gòu)造一個(gè)Handler對(duì)象mServiceHandler谐算,這樣通過mServiceHandler發(fā)送的消息都會(huì)在HandlerThread中執(zhí)行,從這個(gè)角度看归露, IntentService也可以用于執(zhí)行后臺(tái)任務(wù)洲脂。每次啟動(dòng)IntentService,它的onStartCommand方法就會(huì)調(diào)用一次。IntentService在onStartCommand中處理每個(gè)任務(wù)的Intent恐锦。onStartCommand方法中調(diào)用start方法處理Intent往果。
- onStartCommand的start方法
public void onStart(Intent intent, int startId){
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
IntentService僅僅是用過mServiceHandler發(fā)送一個(gè)消息,這個(gè)消息會(huì)在HandlerThread中處理一铅。
mServiceHandler收到消息后陕贮,會(huì)將Intent對(duì)象傳遞給onHandlerIntent方法去處理。注意這個(gè)Intent對(duì)象的內(nèi)容和外界startService(Intent)中的intent的內(nèi)容完全一致的潘飘,通過這個(gè)Intent對(duì)象即可解析出外界啟動(dòng)IntentService時(shí)所傳遞的參數(shù)肮之,通過這些參數(shù)就可區(qū)分具體的后臺(tái)任務(wù),這個(gè)在onHandlerIntent方法中就可以對(duì)不同的后臺(tái)任務(wù)做處理了卜录。當(dāng)onHandlerIntent方法執(zhí)行結(jié)束后戈擒,IntentService會(huì)通過stopSelf()來停止服務(wù),那是因?yàn)閟topSelf()會(huì)立刻停止服務(wù)艰毒,而這個(gè)時(shí)候可能還有其他消息未處理筐高,stopSelf(int startId)則會(huì)等待所有的消息都處理完畢后才終止服務(wù)。一般來說stopSelf(int startId)在嘗試停止服務(wù)之前會(huì)判讀最近啟動(dòng)服務(wù)的次數(shù)是否和startId相等丑瞧,如果相等就立即停止服務(wù)柑土,不相等則不停止服務(wù)。
- ServiceHandler的實(shí)現(xiàn)
private final class ServiceHandler extends Handler{
public ServiceHandler(Looper looper){
super(looper);
}
@override
public void handleMessage(Message msg){
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
IntentService的onHandleIntent是一個(gè)抽象方法绊汹,它需要我們?cè)谧宇愔袑?shí)現(xiàn)稽屏,它的作用是從Intent參數(shù)中區(qū)分具體的任務(wù)并執(zhí)行這些任務(wù)。如果目前只存在一個(gè)后臺(tái)任務(wù)灸促,那么onHandleIntent方法執(zhí)行完這個(gè)任務(wù)后诫欠,stopSelf(int startId)就會(huì)直接停止服務(wù);如果目前存在多個(gè)后臺(tái)任務(wù)浴栽,那么當(dāng)onHandleIntent方法執(zhí)行完最后一個(gè)任務(wù)時(shí)荒叼,stopSelf(int startId)才會(huì)直接停止服務(wù)。另外典鸡,由于每執(zhí)行一個(gè)后臺(tái)任務(wù)就必須啟動(dòng)一次IntentService被廓,而IntentService內(nèi)部則通過消息的方式向HandlerThread請(qǐng)求執(zhí)行任務(wù),Handler中Looper是順序處理消息的萝玷,這意味著IntentService也會(huì)順序執(zhí)行后臺(tái)任務(wù)嫁乘,當(dāng)有多個(gè)后臺(tái)任務(wù)同時(shí)存在時(shí),這些后臺(tái)任務(wù)會(huì)按照外界發(fā)起的順序排隊(duì)執(zhí)行球碉。
Android中的線程池
線程池的優(yōu)點(diǎn)
- 重用線程池中的線程蜓斧,避免因?yàn)榫€程的創(chuàng)建和銷毀所帶來的性能開銷。
- 能有效的控制線程池的最大并發(fā)量睁冬,避免大量的線程因?yàn)閾屨枷到y(tǒng)資源而造成的堵塞的現(xiàn)象挎春。
- 能夠?qū)€程進(jìn)行簡單的管理,提供定時(shí)執(zhí)行以及執(zhí)行間隔循環(huán)等功能。
ThreadPoolExecutor
- 構(gòu)造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
corePoolSize 線程池的核心線程數(shù)直奋,默認(rèn)情況下能庆,核心線程會(huì)在線程池中一直存活,即使它們處于閑置狀態(tài)脚线。如果將ThreadPoolExecutor的allowCorePoolTimeOut屬性設(shè)為true搁胆,那么閑置的核心線程在等待執(zhí)行任務(wù)時(shí)會(huì)有超時(shí)策略,超時(shí)時(shí)間由keepAliveTime所指定邮绿。當(dāng)?shù)却龝r(shí)間超過keepAliveTime所指定的時(shí)長后渠旁,核心線程就會(huì)停止。
maximumPoolSize 線程池所能容納的最大線程數(shù)船逮,當(dāng)活動(dòng)線程數(shù)達(dá)到這個(gè)數(shù)值后一死,后續(xù)的新任務(wù)就會(huì)被堵塞。
keepAliveTime 非核心線程閑置時(shí)的超時(shí)時(shí)長傻唾,超過這個(gè)時(shí)長,非核心線程就會(huì)被回收承耿。當(dāng)ThreadPoolExecutor的
allowCorePoolTimeOut屬性為true時(shí)冠骄,keepAliveTime同樣會(huì)作用于核心線程。
unit 用于指定keepAliveTime的時(shí)間單位加袋。
workQueue 線程池中的任務(wù)隊(duì)列凛辣,通過execute提交的runnable對(duì)象會(huì)存儲(chǔ)在這個(gè)參數(shù)中。
threadFactory 線程工廠职烧,為線程池提供創(chuàng)建新線程的功能扁誓。ThreadFactory是一個(gè)接口,它只有一個(gè)方法:Thread newThread
(Runnable r)蚀之。
除了上面的這些主要參數(shù)外蝗敢,ThreadPoolExecutor還有一個(gè)不常用的參數(shù)RejectedExecutionHandler handler。當(dāng)線程無法執(zhí)行新任務(wù)時(shí)足删,這可能是由于任務(wù)隊(duì)列已滿或者是無法成功執(zhí)行任務(wù)寿谴,這個(gè)時(shí)候ThreadPoolExecutor會(huì)調(diào)用handler的rejectedExecution方法來通知調(diào)用者,默認(rèn)情況下rejectedExecution方法會(huì)拋出一個(gè)RejectedExecutionexception失受。
ThreadPoolExecutor為RejectExecutionHandler提供了幾個(gè)可選值:
CallerRunsPolicy讶泰、AbortPolicy、DiscardOldestPolicy拂到,其中AbortPolicy是默認(rèn)值痪署,它會(huì)直接拋出RejectedExecutionException,handler這個(gè)參數(shù)不常用兄旬。
- ThreadPoolExecutor執(zhí)行任務(wù)時(shí)大致遵循以下原則:
- 如果線程池的數(shù)量未達(dá)到核心線程數(shù)量狼犯,那么就會(huì)啟動(dòng)一個(gè)核心線程來執(zhí)行任務(wù)。
- 如果線程池的線程數(shù)量已達(dá)到或者超過核心線程數(shù)量,那么任務(wù)會(huì)被插入到任務(wù)隊(duì)列中排隊(duì)執(zhí)行辜王。
- 如果步驟2中無法將任務(wù)插入到任務(wù)隊(duì)列中劈狐,這往往是由于任務(wù)隊(duì)列已滿,這個(gè)時(shí)候如果線程數(shù)量未達(dá)到線程池規(guī)定的最大值呐馆,那么就會(huì)立即啟動(dòng)一個(gè)非核心線程來執(zhí)行任務(wù)肥缔。
- 如果步驟3中線程數(shù)量已達(dá)到線程池所規(guī)定的最大值,那么就拒絕執(zhí)行這次任務(wù)汹来,ThreadPoolExecutor會(huì)調(diào)用RejectedExcutionHandler的rejectedExecution來通知調(diào)用者续膳。
- ThreadPoolExecutor在AsyncTask中的體現(xiàn)。
private static final int CPU_COUNT = Runtime.getRuntime().AcailableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT+1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT*2+1;
private static final int KEEP_ALIVE = 1;
private static final ThreadFactory sThreadFactory = new ThreadFactory(){
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r){
return new Thread(r,"AsyncTask #"+mCount.getAndIncrement());
}
};
private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
sPoolWorkQueue,
sThreadFactory)
線程池的分類
FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads){
return new ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.MILLISECONEDS,new LinkedBlockingQueue<Runnable>());
}
通過Executors的newFixedThreadPool方法來創(chuàng)建收班,它是一種線程數(shù)量固定的線程池坟岔,當(dāng)線程處于空閑狀態(tài)時(shí),它們并不會(huì)被回收摔桦,除非線程池被關(guān)閉了社付。當(dāng)所有線程都處于活動(dòng)狀態(tài)時(shí),新任務(wù)都會(huì)處于等待狀態(tài)邻耕,直到線程空閑出來鸥咖。由于FixedThreadPool只有核心線程并且核心線程不會(huì)被回收,這意味著他能夠更加快速的響應(yīng)外界的請(qǐng)求兄世。FixedThreadPool中只有核心線程并且核心線程沒有超時(shí)機(jī)制啼辣,另外任務(wù)隊(duì)列也是沒有大小限制。
CachedThreadPool
public static ExecutorService newCachedThreadPool(){
return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONEDS,new SynchronousQueue<Runnable>())
}
通過Executors的呢我CachedThreadPool方法來創(chuàng)建御滩。它是一種線程數(shù)量不定的線程池鸥拧,它只是非核心線程,并且其最大線程數(shù)為Integer.MAX_VALUE削解。由于Integer_MAX_VALUE是一個(gè)很大的數(shù)富弦,實(shí)際上就相當(dāng)于最大線程數(shù)可以死任意大。當(dāng)線程池中的線程都處于活動(dòng)狀態(tài)時(shí)氛驮,線程池會(huì)創(chuàng)建新的線程來處理新任務(wù)舆声,否則就會(huì)利用空閑的線程來處理新任務(wù)。線程池中的空閑線程都有超時(shí)機(jī)制柳爽,CachedThreadPool的任務(wù)隊(duì)列其實(shí)相當(dāng)于一個(gè)空集合媳握,這將導(dǎo)致任何任務(wù)都會(huì)立即執(zhí)行,因?yàn)樵谶@種場景下SynchronousQueue是無法插入任務(wù)的磷脯。SynchronousQueue是一個(gè)非常特殊的隊(duì)列蛾找,在很多情況下可以把它簡單理解為一個(gè)無法存儲(chǔ)元素的隊(duì)列,由于它實(shí)際中較少使用赵誓,這里就不深入探討它了打毛。從CachedThreadPool的特性來看柿赊,這類線程池比較適合執(zhí)行大量的耗時(shí)較少的任務(wù)。當(dāng)中整個(gè)線程池都處于閑置狀態(tài)時(shí)幻枉,線程池中的線程都或超時(shí)而被停止碰声,這個(gè)時(shí)候CachedThreadPool之中實(shí)際上是沒有任何線程的,它幾乎不占任何系統(tǒng)資源的熬甫。
ScheduledThreadPool
public static ScheduleExecutorService newScheduledThreadPool(int corePoolSize){
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize){
super(corePoolSize,Integer.MAX_VALUE,0,NAMOSECONEDS,new DelayWorkQueue());
}
通過Executors的newScheduledThreadPool方法來創(chuàng)建胰挑。它的核心線程數(shù)量是固定的,而非核心線程是沒有限制的椿肩,并且當(dāng)非核心線程閑置時(shí)會(huì)被立即回收瞻颂。ScheduledThreadPool這列線程池主要用于執(zhí)行定時(shí)任務(wù)和具有固定周期的重復(fù)任務(wù)。
SingleThreadPool
public static ExecutorService newSingleThreadExecutor(){
return new FinalizableDelegateExecutorService(new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
通過Executors的newSingleThreadExecutor方法來創(chuàng)建郑象。這類線程池內(nèi)部只有一個(gè)核心線程贡这,它確保所有任務(wù)都在同一個(gè)線程中順序執(zhí)行。SingleThreadExecutor的意義在于統(tǒng)一所有外界任務(wù)到一個(gè)線程中厂榛,這使得在這些任務(wù)之間不需要出來線程同步的問題盖矫。
- 使用方法
Runnable command = new Runnable(){
@Override
public void run(){
SystemClock.sleep(2000);
}
};
ExecutorService fixedThreadPool = Executors.newDixedThreadPool(4);
fixedThreadPool.execute(command);
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
cachedThreadPool.execute(command);
ScheduleExecutorsService scheduledThreadPool = Executors.newScheduledThreadPool(4);
//2000ms后執(zhí)行command
scheduledThreadPool.schedule(command,2000,TimeUnit.MILLISECONDS);
//延遲10ms后,每隔1000ms執(zhí)行一次command
scheduledThreadPool.scheduleAtFixedRate(command,10,1000,TimeUnit.MILLISECONDS);
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
singleThreadExecutor.execute(command);