1.CachedThreadPool
CachedThreadPool首先会按照需要创建足够多的线程来执行任务(Task)。随着程序执行的过程,有的线程执行完了任务,可以被重新循环使用时,才不再创建新的线程来执行任务。
doSomeThing(int id)方法模拟耗时操作。
private static void doSomething(int id) {
System.out.println("start do " + id + " task ..." + "--threadId="
+ Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished do " + id + " task..."+ "--threadId="
+ Thread.currentThread().getId());
}
测试代码:
static int i;
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (i = 0; i < 5; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
doSomething(i);
}
});
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executorService.shutdown();
System.out.println(">>main thread end.");
}
测试结果:
start do 1 task ...--threadId=8
start do 2 task ...--threadId=9
finished do 1 task...--threadId=8
start do 3 task ...--threadId=8
finished do 2 task...--threadId=9
start do 4 task ...--threadId=9
finished do 3 task...--threadId=8
start do 5 task ...--threadId=8
>>main thread end.
finished do 4 task...--threadId=9
finished do 5 task...--threadId=8
可以看到,当执行到任务2时(距离开始200ms),任务1(耗时300ms)还未执行完,所以开启新线程thread-9; 当执行到任务3时(距离开始400ms),任务1已经执行完毕,thread-8处于空闲状态,所以用thread-8执行任务3,以此类推。
2.FixedThreadPool
FixedThreadPool模式会使用一个优先固定数目的线程来处理若干数目的任务。规定数目的线程处理所有任务,一旦有线程处理完了任务就会被用来处理新的任务(如果有的话)。这种模式与上面的CachedThreadPool是不同的,CachedThreadPool模式下处理一定数量的任务的线程数目是不确定的。而FixedThreadPool模式下最多 的线程数目是一定的。
采用FixedThreadPool模式编写客户端程序如下:
static int i;
public static void main(String[] args) {
ExecutorService executorService =Executors.newFixedThreadPool(3);
for (i = 0; i < 5; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
doSomething(i);
}
});
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executorService.shutdown();
System.out.println(">>main thread end.");
}
测试结果:
start do 1 task ...--threadId=8
start do 2 task ...--threadId=9
finished do 1 task...--threadId=8
start do 3 task ...--threadId=10
finished do 2 task...--threadId=9
start do 4 task ...--threadId=8
finished do 3 task...--threadId=10
start do 5 task ...--threadId=9
>>main thread end.
finished do 4 task...--threadId=8
finished do 5 task...--threadId=9
这种线程池无论当前池里是否有空闲的线程都继续创建新的线程,直至达到指定数量的线程为止。
3.SingleThreadExecutor模式
SingleThreadExecutor模式只会创建一个线程。它和FixedThreadPool比较类似,不过线程数是一个。如果多个任务被提交给SingleThreadExecutor的话,那么这些任务会被保存在一个队列中,并且会按照任务提交的顺序,一个先执行完成再执行另外一个线程。
SingleThreadExecutor模式可以保证只有一个任务会被执行。这种特点可以被用来处理共享资源的问题而不需要考虑同步的问题。
SingleThreadExecutor模式编写的客户端程序如下:
public static void main(String[] args) {
ExecutorService executorService =
Executors.newSingleThreadExecutor();
for (i = 0; i < 5; i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.submit(new Runnable() {
@Override
public void run() {
doSomething(i);
}
});
}
executorService.shutdown();
System.out.println(">>main thread end.");
}
测试结果(只有一个线程,效果与newFixedThreadPool(1)相同):
start do 1 task ...--threadId=8
finished do 1 task...--threadId=8
start do 2 task ...--threadId=8
finished do 2 task...--threadId=8
start do 4 task ...--threadId=8
>>main thread end.
finished do 4 task...--threadId=8
start do 5 task ...--threadId=8
finished do 5 task...--threadId=8
start do 5 task ...--threadId=8
finished do 5 task...--threadId=8