1.CachedThreadPool
CachedThreadPool首先會按照需要創(chuàng)建足夠多的線程來執(zhí)行任務(wù)(Task)。隨著程序執(zhí)行的過程,有的線程執(zhí)行完了任務(wù),可以被重新循環(huán)使用時,才不再創(chuàng)建新的線程來執(zhí)行任務(wù)。我們采用《Thinking In Java》中的例子來分析。
首先,任務(wù)定義如下(實現(xiàn)了Runnable接口,并且復寫了run方法):
package net.jerryblog.concurrent;public class LiftOff implements Runnable{
protected int countDown = 10; //Default
private static int taskCount = 0;
private final int id = taskCount++;
public LiftOff() {}
public LiftOff(int countDown) {
this.countDown = countDown;
}
public String status() {
return "#" + id + "(" +
(countDown > 0 ? countDown : "LiftOff!") + ") ";
}
@Override
public void run() {
while(countDown-- > 0) {
System.out.print(status());
Thread.yield();
}
}
}
采用CachedThreadPool方式執(zhí)行編寫的客戶端程序如下:
package net.jerryblog.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 10; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
上面的程序中,有10個任務(wù),采用CachedThreadPool模式,exec沒遇到一個LiftOff的對象(Task),就會創(chuàng)建一個線程來處理任務(wù)。現(xiàn)在假設(shè)遇到到第4個任務(wù)時,之前用于處理第一個任務(wù)的線程已經(jīng)執(zhí)行完成任務(wù)了,那么不會創(chuàng)建新的線程來處理任務(wù),而是使用之前處理第一個任務(wù)的線程來處理這第4個任務(wù)。接著如果遇到第5個任務(wù)時,前面那些任務(wù)都還沒有執(zhí)行完,那么就會又新創(chuàng)建線程來執(zhí)行第5個任務(wù)。否則,使用之前執(zhí)行完任務(wù)的線程來處理新的任務(wù)。
2.FixedThreadPool
FixedThreadPool模式會使用一個優(yōu)先固定數(shù)目的線程來處理若干數(shù)目的任務(wù)。規(guī)定數(shù)目的線程處理所有任務(wù),一旦有線程處理完了任務(wù)就會被用來處理新的任務(wù)(如果有的話)。這種模式與上面的CachedThreadPool是不同的,CachedThreadPool模式下處理一定數(shù)量的任務(wù)的線程數(shù)目是不確定的。而FixedThreadPool模式下最多 的線程數(shù)目是一定的。
采用FixedThreadPool模式編寫客戶端程序如下:
package net.jerryblog.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPool {
public static void main(String[] args) {
//三個線程來執(zhí)行五個任務(wù)
ExecutorService exec = Executors.newFixedThreadPool(3);
for(int i = 0; i < 5; i++) {
exec.execute(new LiftOff());
}
exec.shutdown();
}
}
3.SingleThreadExecutor模式
SingleThreadExecutor模式只會創(chuàng)建一個線程。它和FixedThreadPool比較類似,不過線程數(shù)是一個。如果多個任務(wù)被提交給SingleThreadExecutor的話,那么這些任務(wù)會被保存在一個隊列中,并且會按照任務(wù)提交的順序,一個先執(zhí)行完成再執(zhí)行另外一個線程。
SingleThreadExecutor模式可以保證只有一個任務(wù)會被執(zhí)行。這種特點可以被用來處理共享資源的問題而不需要考慮同步的問題。
SingleThreadExecutor模式編寫的客戶端程序如下:
package net.jerryblog.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < 2; i++) {
exec.execute(new LiftOff());
}
}
}
這種模式下執(zhí)行的結(jié)果如下:
#0(9) #0(8) #0(7) #0(6) #0(5) #0(4) #0(3) #0(2) #0(1) #0(LiftOff!)
#1(9) #1(8) #1(7) #1(6) #1(5) #1(4) #1(3) #1(2) #1(1) #1(LiftOff!)
第一個任務(wù)執(zhí)行完了之后才開始執(zhí)行第二個任務(wù)。