Executors的newSingleThreadExecutor()和newFixedThreadPool(1)有什么区别?

https://segmentfault.com/q/1010000011185322

Executors的newSingleThreadExecutor()和newFixedThreadPool(1)有什么区别?

参考了一些文章,都说newSingleThreadExecutor()主要有两个特性:

  1. 能保证执行顺序,先提交的先执行。
  2. 当线程执行中出现异常,去创建一个新的线程替换之。

讲到和newFixedThreadPool(1)的区别,都主要指出如下。

http://www.cnblogs.com/richaa...文章中:

和 newFixedThreadPool(1) 的区别在于,如果线程遇到错误中止,它是无法使用替代线程的。

http://blog.csdn.net/vking_wa...文章中:

如果当前线程意外终止,会创建一个新线程继续执行任务,这和我们直接创建线程不同,也和newFixedThreadPool(1)不同。

但经过我的实验(代码如下),得出两者都是一样的,都保证了12

//  ExecutorService executorService = Executors.newSingleThreadExecutor();
    ExecutorService executorService = Executors.newFixedThreadPool(1);
        
    executorService.execute(
        () -> {
            if (count == 100) {
                thrownewIllegalStateException("handler exception");
            }
            System.out.println(Thread.currentThread()+" - testAsyncRunner1 run ... "+count);
        }
    );
        

运行结果:

Thread[pool-1-thread-1,5,main] - testAsyncRunner1 run ... 99
Exception in thread "pool-1-thread-1" java.lang.IllegalStateException: handler exception
    at com.mxx.meal.common.core.async.AsyncHandlerFactoryTest.lambda$null$0(AsyncHandlerFactoryTest.java:32)
    at com.mxx.meal.common.core.async.AsyncHandlerFactoryTest$$Lambda$2/830539025.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Thread[pool-1-thread-2,5,main] - testAsyncRunner1 run ... 101

创建newSingleThreadExecutor的源码中,其实是在newFixedThreadPool(1)的基础上包装了FinalizableDelegatedExecutorService,请问下这个究竟有啥用?麻烦帮忙解答。

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

3个回答

答案对人有帮助,有参考价值 2 答案没帮助,是错误的答案,答非所问

已采纳

看了下FinalizableDelegatedExecutorService,就是多了个gc时停掉线程池的功能。

static class FinalizableDelegatedExecutorService
        extends DelegatedExecutorService {
        FinalizableDelegatedExecutorService(ExecutorService executor) {
            super(executor);
        }
        
        //GC的时候停掉线程池
        protected void finalize() {
            super.shutdown();
        }
    }

父类DelegatedExecutorService 基本就是个装饰器模式,调用传进来的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(); }
        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);
        }
    }

所以这两个线程池类型是没什么区别的。

答案对人有帮助,有参考价值 2 答案没帮助,是错误的答案,答非所问
     //  Unlike the otherwise equivalent
     // {@code newFixedThreadPool(1)} the returned executor is
     // guaranteed not to be reconfigurable to use additional threads.
      public static ExecutorService newSingleThreadExecutor() 

这是jdk8源码上面的注释,大体上的意思是 newSingleThreadExecutor 不能配置去重新加入线程;
接下来 举个栗子

    // final ExecutorService single = Executors.newSingleThreadExecutor();
       final ExecutorService fixed = Executors.newFixedThreadPool(1);
        ThreadPoolExecutor executor = (ThreadPoolExecutor) fixed;
        executor.setCorePoolSize(4);

就是上面的意思
为什么呢?

 /**
     * A wrapper class that exposes only the ExecutorService methods
     * of an ExecutorService implementation.
     */
    static class DelegatedExecutorService extends AbstractExecutorService 

看上面的代码 FinalizableDelegatedExecutorService extends DelegatedExecutorService,而DelegatedExecutorService的主要作用就是不暴露那么多方法,不让你配置线程池,至此,single就真的single了

以上


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值