併發包學習:線程池之Executor,Executors,ExecutorService

線程池

public interface Executor {

    void execute(Runnable command);
}

Executor沒什麼說的,線程池頂層接口,只有一個方法execute。

Executors是對線程執行的工具類,可以看做是線程的工廠,用來產生各種線程池

簡單複習下

帶緩存的,可以看到,存活時間60s,60s沒用到就會被回收,
隊列是SynchronousQueue,來一個線程之前必須得走一個,不然就阻塞
沒有線程工廠就用默認的
拒絕策略也是默認的。不用指定  
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

  public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }



指定固定大小的線程池,沒啥說的

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

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



定時的,這裏有區別,她是new ScheduledThreadPoolExecutor這個的,這個類以後細看吧,
主要是使用的隊列是DelayedWorkQueue這個
參數是核心線程數

 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

    
    public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    }



還有一個是單例的,就是隻有一個線程,爲什麼會有單個線程的線程池呢,因爲線程池是有任務隊列的
生命週期管理線程池可以幫你提供的。

 

ExecutorService

ExecutorService繼承於Executor,它提供一些可以管理任務的執行、取消、結束的方法。

shutdown方法

void shutdown();

shutdown方法調用之後,馬上拒絕接收新的任務,但是之前已經提交的任務會繼續執行。

shutdownNow方法

List<Runnable> shutdownNow();

該函數調用之後,馬上拒絕接收新的任務,並且會嘗試結束當前正在執行的任務,直到所有任務真正結束爲止,並且會返回等待執行的任務的列表。

isShutdown方法

boolean isShutdown();

該函數判斷service是否已經被shutdown,如果調用過shutdown函數,則返回true,否則返回false。

isTerminated方法

boolean isTerminated();

該函數判斷service中得所有任務是否已經全部執行完畢,並且應該注意的是:如果沒有調用過shutdown函數或者shutdownNow函數,該函數的返回值不可能爲true。

awaitTermination方法

boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;

該函數會一直阻塞直到所有的任務已經被執行或者等待時間到。

submit方法

<T> Future<T> submit(Callable<T> task);

<T> Future<T> submit(Runnable task, T result);

Future<?> submit(Runnable task);

這些函數都是向service提交一個任務,並且返回一個Futrue對象,用於追蹤任務的執行情況。區別在於第一個函數在任務執行完畢之後Futrue.get()將會返回任務執行的結果,第二個函數在任務執行完畢之後Future.get()將會返回給定的result結果,而第三個函數在任務執行完畢之後Future.get()將會返回null。

invokeAll方法

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException;

這些方法比較好理解,就是執行任務列表中的所有任務,並返回與每個任務對應的Futue。也就是說,任務彼此之間不會相互影響,可以通過future跟蹤每一個任務的執行情況,比如是否被取消,是正常完成,還是異常完成,這主要使用Future類提供的API。invokeAll是一個阻塞方法,會等待任務列表中的所有任務都執行完成。不管任務是正常完成,還是異常終止,Future.isDone()始終返回true。通過
Future.isCanceled()可以判斷任務是否在執行的過程中被取消。通過Future.get()可以獲取任務的返回結果,或者是任務在執行中拋出的異常。

invokeAny方法

<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;

<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

上面的函數執行給定的一系列任務,當某一個任務成功執行(沒有拋出異常)時,返回該任務對應的Future對象,其他所有未被執行的任務都將取消。如果執行過程中修改了tasks列表,則返回的結果是不確定的。第二個函數帶有超時時間。此外還應該注意:

  • 一旦有1個任務正常完成(執行過程中沒有拋異常),線程池會終止>其他未完成的任務 。
  • 如果提交的任務列表中,沒有1個正常完成的任務,那麼調用invokeAny會拋異常,究竟拋的是哪兒個任務的異常,無關緊要
  • invokeAny()和任務的提交順序無關,只是返回最早正常執行完成的任務
  • 如果在超時之前,所有任務已經都是異常終止,那就沒有必要在等下去了;如果超時之後,仍然有正在運行或等待運行的任務,那麼會拋出TimeoutException。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章