about_newSingleThreadExecutor

关于 Executors.newSingleThreadExecutor()

本以为只是一个简单的单线程线程池,与 Executors.newFixedThreadExecutor(1) 类似,但它的 DOC 注释中又显式提到:

Unlike the otherwise equivalent {@code newFixedThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads.

与类似功能的 newFixedThreadPool(1) 不一样,该方法返回的线程池执行器不可以被重新配置以使用额外的线程。

关键在于不可以重新配置。来看看它的构造器:

1
2
3
4
5
public static ExecutorService newSingleThreadExecutor() {
// FinalizableDelegatedExecutorService 装饰器
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* FinalizableDelegatedExecutorService 装饰器,普普通通。但多了一个 finalize() 方法。
*/
static class FinalizableDelegatedExecutorService extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
// 关于 finalize(),在『深入理解Java虚拟机』中有提到:可达性分析后,没有与 GC Roots 相连接的对象
// 如果 Override 了 finalize(),且该方法还没有被执行过,则该对象会被添加到 F-Queue 的队列中,并
// 稍后在一个由虚拟机发起的自动建立的、低优先级的 Finalizer 线程中去执行 finalize(),但并不承诺会
// 等到该方法执行完成。
// FinalizableDelegatedExecutorService 会尝试在被 GC 时关闭线程池。
protected void finalize() {
super.shutdown();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* A wrapper class that exposes only the ExecutorService methods
* of an ExecutorService implementation.
* 仅暴露 ExecutorService 接口的方法
*/
static class DelegatedExecutorService extends AbstractExecutorService {
private final ExecutorService e;
// 构造方法
DelegatedExecutorService(ExecutorService executor) { e = executor; }
public void execute(Runnable command) { e.execute(command); }
public void shutdown() { e.shutdown(); }
...
}

再看看 ThreadPoolExecutor 的实现:👇

1
2
3
4
/**
* ThreadPoolExecutor 和 DelegatedExecutorService 一样都是 AbstractExecutorService 抽象类的子类
*/
public class ThreadPoolExecutor extends AbstractExecutorService

那我们试试,reconfigurable newSingleThreadExecutor 会怎样:👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void singleThreadPoolExecutorTest(){
ExecutorService fixed = Executors.newFixedThreadPool(1);
ThreadPoolExecutor t1 = (ThreadPoolExecutor)fixed;
// 正常执行
t1.setCorePoolSize(2);

ExecutorService single = Executors.newSingleThreadExecutor();
// 强转报错:java.lang.ClassCastException: java.util.concurrent.Executors$FinalizableDelegatedExecutorService cannot be cast to java.util.concurrent.ThreadPoolExecutor
// 都是 AbstractExecutorService 的子类,没法儿强转
ThreadPoolExecutor t2 = (ThreadPoolExecutor)single;
t2.setCorePoolSize(2);
}

/**
* newFixedThreadPool 返回的是 ThreadPoolExecutor,ThreadPoolExecutor 有 setCorePoolSize(),
* 自然没问题。
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}