Executors的newSingleThreadExecutor()和newFixedThreadPool(1)有什麼區別?

 

 

Executors的newSingleThreadExecutor()和newFixedThreadPool(1)有什麼區別?php

參考了一些文章,都說newSingleThreadExecutor()主要有兩個特性:java

  1. 能保證執行順序,先提交的先執行。
  2. 當線程執行中出現異常,去建立一個新的線程替換之。

講到和newFixedThreadPool(1)的區別,都主要指出以下。app

 

和 newFixedThreadPool(1) 的區別在於,若是線程遇到錯誤停止,它是沒法使用替代線程的。async

 

若是當前線程意外終止,會建立一個新線程繼續執行任務,這和咱們直接建立線程不一樣,也和newFixedThreadPool(1)不一樣。ide

但通過個人實驗(代碼以下),得出二者都是同樣的,都保證了12gradle

//  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);
        }
    );

運行結果:ui

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,請問下這個究竟有啥用?麻煩幫忙解答。spa

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(); } }static class FinalizableDelegatedExecutorService extends DelegatedExecutorService { FinalizableDelegatedExecutorService(ExecutorService executor) { super(executor); } //GC的時候停掉線程池 protected void finalize() { super.shutdown(); } }

父類DelegatedExecutorService 基本就是個裝飾器模式,調用傳進來的ExecutorService實例方法。scala

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了

以上

相關文章
相關標籤/搜索