Java線(xiàn)程池相關(guān)類(lèi)
Java線(xiàn)程池相關(guān)類(lèi)
Executor
定義了最常見(jiàn)的線(xiàn)程池接口肢娘,execute(Runnable command)
揪漩。
public interface Executor {
void execute(Runnable command);
}
ExecutorService
線(xiàn)程池接口類(lèi)寒屯。
ThreadPoolEexcutor
最為常用的線(xiàn)程池互捌。
/**
* corePoolSize : 活躍線(xiàn)程數(shù)
* maximumPoolSize : 線(xiàn)程總數(shù)
* keepAliveTime,unit : 非活躍線(xiàn)程在keepAliveTime個(gè)unit之后會(huì)被回收
* workQueue : 工作隊(duì)列
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {}
Executors
工廠(chǎng)類(lèi)辐棒,利用工廠(chǎng)方法可以生產(chǎn)成各種各樣的線(xiàn)程池病曾,生產(chǎn)出各種參數(shù)的ThreadPoolExecutor,比如newFixedThreadPool(int nThreads)
:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
ThreadPoolExecutor
- 當(dāng)線(xiàn)程池執(zhí)行一個(gè)runnable時(shí)漾根,它會(huì)先去檢查線(xiàn)程池里的線(xiàn)程數(shù)是否小于corePool的定義的線(xiàn)程數(shù)泰涂,如果小于它,不管這些線(xiàn)程是否空閑辐怕,都會(huì)不斷創(chuàng)建新線(xiàn)程逼蒙,直到線(xiàn)程池里的線(xiàn)程數(shù)等于corePool。
- 當(dāng)線(xiàn)程池的線(xiàn)程數(shù)已經(jīng)等于corePool寄疏,如果還有新任務(wù)是牢,但是線(xiàn)程池里面有空閑線(xiàn)程,那么會(huì)用這些空閑線(xiàn)程執(zhí)行這些任務(wù)陕截。
- 如果線(xiàn)程池里面已經(jīng)沒(méi)有空閑線(xiàn)程了驳棱,會(huì)把任務(wù)放到工作隊(duì)列里面;當(dāng)有線(xiàn)程閑下來(lái)的時(shí)候农曲,會(huì)從工作隊(duì)列里面取任務(wù)下來(lái)執(zhí)行社搅。
- 當(dāng)沒(méi)有空閑線(xiàn)程,并且工作隊(duì)列也已經(jīng)滿(mǎn)了乳规。這時(shí)會(huì)從創(chuàng)建新線(xiàn)程來(lái)執(zhí)行這些任務(wù)形葬,直到線(xiàn)程池的線(xiàn)程數(shù)等于maximumPool
- 如果工作的線(xiàn)程數(shù)已經(jīng)達(dá)到maximumPoolSize,并且工作隊(duì)列也已經(jīng)被塞滿(mǎn)了暮的,這時(shí)如果還來(lái)新任務(wù)的話(huà)就會(huì)報(bào)異常笙以。
- 當(dāng)線(xiàn)程不再執(zhí)行任務(wù)的時(shí)候,過(guò)了keepAliveTime冻辩,如果線(xiàn)程池總數(shù)大于corePoolSize猖腕,就會(huì)被回收,直到線(xiàn)程池的總數(shù)等于corePoolSize微猖。
假設(shè)corePool = 3谈息, maximumPool = 6缘屹, 工作隊(duì)列大小為10個(gè)凛剥,假設(shè)這些線(xiàn)程都需要足夠的時(shí)間才能執(zhí)行完畢,當(dāng)加入20個(gè)任務(wù)的時(shí)候轻姿,線(xiàn)程執(zhí)行順序應(yīng)該是這樣子的:先執(zhí)行1-3犁珠,然后把4-13放到工作隊(duì)列里面逻炊,然后再執(zhí)行14-16,任務(wù)17-20會(huì)拋出異常犁享。
Callable和Future
Callable 和 Runnable都可以作為線(xiàn)程的執(zhí)行任務(wù)余素,只是Callable有返回值,而Runnable沒(méi)有返回值炊昆;Callable的返回值可以用Future來(lái)接收桨吊,然后用get()來(lái)使用。比如:
ExecutorService pool = Executors.newFixedThreadPool(10);
Future<String> future = pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
});
System.out.println(future.get());
future.get()
會(huì)使線(xiàn)程阻塞凤巨,一直到call執(zhí)行完视乐。
FutureTask
ExecutorService pool = Executors.newFixedThreadPool(10);
FutureTask futureTask = new FutureTask(new Callable<String>() {
@Override
public String call() throws Exception {
return Thread.currentThread().getName();
}
});
pool.submit(futureTask);
//用普通線(xiàn)程的方式
new Thread(futureTask).start();
if(futureTask.isDone()){
System.out.println(futureTask.get());
}