ThreadPoolExecutor填坑日志(1)——newFixedThreadPool(1)与newSingleThreadPool()的区别

两种工厂方法区别

ThreadPoolExecutor是Executors类的底层实现,在JDK帮助文档中,有如此一段话:“强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。”

看了一下Executors.newFixedThreadPool(int)和Executors.newSingleThreadExecutor()的源码:

public static ExecutorService newFixedThreadPool(int nThreads) {  
       return new ThreadPoolExecutor(nThreads, nThreads,  
                                        0L, TimeUnit.MILLISECONDS,  
                                        new LinkedBlockingQueue<Runnable>());  
      }  
public static ExecutorService newSingleThreadExecutor() {  
        return new FinalizableDelegatedExecutorService  
            (new ThreadPoolExecutor(1, 1,  
                                    0L, TimeUnit.MILLISECONDS,  
                                    new LinkedBlockingQueue<Runnable>()));  
    }  

发现newSingleThreadExecutor()与newFixedThreadPool(1)的区别就是newSingleThreadExecutor()是被FinalizableDelegatedExecutorService包装了一下,FinalizableDelegatedExecutorService的代码如下:

static class FinalizableDelegatedExecutorService
    extends DelegatedExecutorService {
    FinalizableDelegatedExecutorService(ExecutorService executor) {
        super(executor);
    }
    protected void finalize() {
        super.shutdown();
    }
}

DelegatedExecutorService的源码如下:

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(); }
    public List<Runnable> shutdownNow() { return e.shutdownNow(); }
    public boolean isShutdown() { return e.isShutdown(); }
    public boolean isTerminated() { return e.isTerminated(); }
    public boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException {
        return e.awaitTermination(timeout, unit);
    }
    public Future<?> submit(Runnable task) {
        return e.submit(task);
    }
    public <T> Future<T> submit(Callable<T> task) {
        return e.submit(task);
    }
    public <T> Future<T> submit(Runnable task, T result) {
        return e.submit(task, result);
    }
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException {
        return e.invokeAll(tasks);
    }
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                             long timeout, TimeUnit unit)
        throws InterruptedException {
        return e.invokeAll(tasks, timeout, unit);
    }
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException {
        return e.invokeAny(tasks);
    }
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                               long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        return e.invokeAny(tasks, timeout, unit);
    }
}

它是线程池的一个代理模式的实现,对线程池所有方法的调用其实是被到了委托类上,不过委托的功能是被阉割的, 因为只实现并委托了部分方法,真实线程池存在的那些未被委托的方法在这里将无法使用。那么这样的目的是什么呢?JDK的源码注释是这么写的:

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

意思是 newSingleThreadExecutor 不能通过重新配置加入线程,即:

final ExecutorService single = Executors.newSingleThreadExecutor();
ThreadPoolExecutor executor = (ThreadPoolExecutor) single;
// 报错
executor.setCorePoolSize(5);

这样就无法在创建了newSingleThreadExecutor以后再把它重新设置为多线程池,保证了单线程池一旦被创建就永远只能为单线程。

参考

https://my.oschina.net/weiweiblog/blog/484543
https://www.jianshu.com/p/2b7d853322bb
https://segmentfault.com/q/1010000011185322/a-1020000011188451

你可能感兴趣的:(多线程,java)