目录
1、newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
使用方法:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
底层实现:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}
通过看其实现可以发现,他实际上是创建一个核心池为0,最大线程为MAX_VALUE的线程池,该线程池使用SynchronousQueue队列。每次添加任务若没有空闲的线程都会创建新的线程去执行。
使用demo:
@Test
public void test_newCachedThreadPool() throws InterruptedException{
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
cachedThreadPool.execute(new Runnable() {
public void run() {
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
});
}
Thread.sleep(100000L);
}
运行结果:
可以看到只有一次复用了线程。其他时候都是新创建一个线程执行。
2、newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
使用方法:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
底层实现:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
通过看其实现可以发现,他实际上是创建一个核心池、最大线程都为nThreads的固定线程数量的线程池,keepAliveTime为0,标识线程永久存活。该线程池使用LinkedBlockingQueue基于链表的队列,最大长度为Integer.MAX_VALUE。
使用demo:
@Test
public void test_newFixedThreadPool() throws InterruptedException{
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
}
System.out.println(index + " : "+Thread.currentThread().getName());
}
});
}
Thread.sleep(100000L);
}
运行结果:
从运行结果可以看到,最多只创建了3个线程。去进行任务处理。
3、newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
对于newScheduledThreadPool 的使用和讲解
4、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
newFixedThreadPool(1)和newSingleThreadExecutor的区别
Unlike the otherwise equivalent {@code newFixedThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads.
newFixedThreadPool(1)在功能上可以实现newSingleThreadExecutor,但是其区别是使用newSingleThreadExecutor,返回的对象是禁止修改的。比如说,通过返回的对象重新设置核心线程池大小。
例如下面的例子,将newFixedThreadPool的核心池由2改为5,同样的做法,使用newSingleThreadExecutor则会报错。:
使用方法:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
底层实现:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
通过看其实现可以发现,他实际上是先创建一个核心池、最大线程都为1的固定线程数量的线程池,keepAliveTime为0,标识线程永久存活。该线程池使用LinkedBlockingQueue基于链表的队列,最大长度为Integer.MAX_VALUE。然后对这个线程池对象进行封装。
使用demo:
@Test
public void test_newSingleThreadExecutor() throws InterruptedException{
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
public void run() {
try {
System.out.println("按先进先出的顺序执行:"+index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
Thread.sleep(100000L);
}
运行结果:
可以看到,是按照任务的添加顺序执行的