說明
簡單理解和使用可以參考:https://www.cnblogs.com/LQBlog/p/8735356.html
類圖
接口
Executor接口
public interface Executor { /** * 代表提交了一個任務 * @param command */ void execute(Runnable command); }
簡單的實現
1.希望同步執行任務的實現
public class SimpleExecutor implements Executor { @Override public void execute(Runnable command) { command.run();; } }
2.基於線程運行任務的實現
public class ThreadExecutor implements Executor{ @Override public void execute(Runnable command) { new Thread(command).start(); } }
ExecutorService接口
Executor太簡單了,只能提交任務,往往我們需要關注線程池狀態,執行了多少個任務,完成多少個任務,線程池塘線程數量等,Excutor不能滿足,所以需要看ExecutorService接口基於Executor的擴展public interface
class ExecutorService extends Executor { /** * 關閉線程池,已提交的任務繼續執行,不接受繼續提交新任務 */ void shutdown(); /** * 關閉線程池,嘗試停止正在執行的所有任務,不接受繼續提交新任務 * 它和前面的方法相比,加了一個單詞“now”,區別在於它會去停止當前正在進行的任務 * * @return */ List<Runnable> shutdownNow(); /** * 判斷線程池是否已關閉 * @return */ boolean isShutdown(); /** * 如果調用了 shutdown() 或 shutdownNow() 方法後,所有任務結束了,那麼返回true * 這個方法必須在調用shutdown或shutdownNow方法之後調用纔會返回true */ boolean isTerminated(); /** * 等待所有任務完成,並設置超時時間 * 我們這麼理解,實際應用中是,先調用 shutdown 或 shutdownNow, * 然後再調這個方法等待所有的線程真正地完成,返回值意味着有沒有超時 InterruptedException if interrupted while waiting */ boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; /** * 提交一個 Callable 任務 內部會包裝成Future */ <T> Future<T> submit(Callable<T> task); /** * 提交一個 Runnable 任務,第二個參數將會放到 Future 中,作爲返回值, * 因爲 Runnable 的 run 方法本身並不返回任何東西 內部會用Future包裝 */ <T> Future<T> submit(Runnable task, T result); /** * 提交一個 Runnable 任務 */ Future<?> submit(Runnable task); /** * 執行所有任務,返回 Future 類型的一個 list*/ <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; /** * 只有其中的一個任務結束了,就可以返回,返回執行完的那個任務的結果*/ <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; /** * 同上一個方法,只有其中的一個任務結束了,就可以返回,返回執行完的那個任務的結果, * 不過這個帶超時,超過指定的時間,拋出 TimeoutException 異常*/ <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
AbstractExecutorService
是一個抽象類,對ExecutorService的相關方法進行了實現
public abstract class AbstractExecutorService implements ExecutorService { /** * 包裝成futureTask */ protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value); } /** * 包裝成futureTask */ protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); } /** * 包裝成futureTask */ public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); //具體執行任務交給子類執行 execute(ftask); return ftask; } /** * 包裝成futureTask */ public <T> Future<T> submit(Runnable task, T result) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task, result); //具體執行任務交給子類執行 execute(ftask); return ftask; } /** * 包裝成futureTask */ public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; } /** * */ private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks, boolean timed, long nanos) throws InterruptedException, ExecutionException, TimeoutException { if (tasks == null) throw new NullPointerException(); int ntasks = tasks.size(); if (ntasks == 0) throw new IllegalArgumentException(); //初始化task list容器 ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks); //交給ExecutorCompletionService 只負責調度,最終內部執行任務還是調用的 this的execute ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this); try { ExecutionException ee = null; //是不是帶有超時時間的 final long deadline = timed ? System.nanoTime() + nanos : 0L; Iterator<? extends Callable<T>> it = tasks.iterator(); //預執行第一個任務 ecs.submit內部也是調用 當前對象的execute futures.add(ecs.submit(it.next())); //task數量-1 --ntasks; //提交的任務數 int active = 1; //遍歷 for (;;) { //獲取執行結果內部是調用ecs completionQueue如果返回會將結果放入此queue Future<T> f = ecs.poll(); //如果上一個任務沒有執行完畢,針對第一次則是與預執行那個任務,則繼續提交任務 if (f == null) { //表示還有任務 繼續提交任務 if (ntasks > 0) { --ntasks; futures.add(ecs.submit(it.next())); ++active; } else if (active == 0)//當爲0 表示下面 f!=null 每次都異常 任務沒有了 結束 break; else if (timed) {//當任務提交完畢,則最後調用poll嘗試等待指定時機 f = ecs.poll(nanos, TimeUnit.NANOSECONDS); if (f == null)//等待指定四航局 還未獲取到結果則拋出超時異常 throw new TimeoutException(); nanos = deadline - System.nanoTime(); } else//非超時執行task f = ecs.take(); } //表示獲取到結果 if (f != null) { --active;//-1 try { return f.get();//如果是異常結果 則繼續循環檢查下一個任務 } catch (ExecutionException eex) { ee = eex; } catch (RuntimeException rex) { ee = new ExecutionException(rex); } } } //走到這裏則是所有任務異常情況未能正常返回拋出異常 if (ee == null) ee = new ExecutionException(); throw ee; } finally { // 方法退出之前,取消其他的任務 for (int i = 0, size = futures.size(); i < size; i++) futures.get(i).cancel(true); } } public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { try { //調用doInvokeAny return doInvokeAny(tasks, false, 0); } catch (TimeoutException cannotHappen) { assert false; return null; } } public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { //調用doInvokeAny return doInvokeAny(tasks, true, unit.toNanos(timeout)); } public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { if (tasks == null) throw new NullPointerException(); ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); boolean done = false; try { for (Callable<T> t : tasks) { //包裝成future RunnableFuture<T> f = newTaskFor(t); //加入futures futures.add(f); //執行任務並調用子類的execute方法 execute(f); } //遍歷檢查所有任務結果 for (int i = 0, size = futures.size(); i < size; i++) { Future<T> f = futures.get(i); if (!f.isDone()) { try { // 這是一個阻塞方法,直到獲取到值,或拋出了異常 // 這裏有個小細節,其實 get 方法簽名上是會拋出 InterruptedException 的 // 可是這裏沒有進行處理,而是拋給外層去了。此異常發生於還沒執行完的任務被取消了 f.get(); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } } //表示都檢查完畢 done = true; //返回結果 return futures; } finally { //上面執行任務檢查並沒有cache所有異常,以及execute提交任務拒絕策略也會拋出異常,、針對這種情況取消其他任務 if (!done) for (int i = 0, size = futures.size(); i < size; i++) futures.get(i).cancel(true); } } public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException { if (tasks == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); boolean done = false; try { for (Callable<T> t : tasks) futures.add(newTaskFor(t)); //計算超時時間 final long deadline = System.nanoTime() + nanos; final int size = futures.size(); // Interleave time checks and calls to execute in case // executor doesn't have any/much parallelism. for (int i = 0; i < size; i++) { execute((Runnable)futures.get(i)); //提交任務也要更新超時時間 nanos = deadline - System.nanoTime(); if (nanos <= 0L) return futures; } for (int i = 0; i < size; i++) { Future<T> f = futures.get(i); if (!f.isDone()) { //超時時間爲0 返回所有任務 if (nanos <= 0L) return futures; try { //嘗試等待, f.get(nanos, TimeUnit.NANOSECONDS); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } catch (TimeoutException toe) { return futures; } //每次重新計算超時時間 nanos = deadline - System.nanoTime(); } } //全部執行完畢 done = true; return futures; } finally { //針對異常取消提交任務 if (!done) for (int i = 0, size = futures.size(); i < size; i++) futures.get(i).cancel(true); } } }
ExecutorCompletionService實現
public class ExecutorCompletionService<V> implements CompletionService<V> { //真正執行任務的地方 我們的線程池對象 private final Executor executor; //線程池對象 private final AbstractExecutorService aes; private final BlockingQueue<Future<V>> completionQueue; /** * 內部類實現了futureTask * 對RunnableFuture進行了增強 */ private class QueueingFuture extends FutureTask<Void> { QueueingFuture(RunnableFuture<V> task) { super(task, null); this.task = task; } /** * 增強方法 */ protected void done() { //任務執行完畢則將task加入completionQueue completionQueue.add(task); } private final Future<V> task; } private RunnableFuture<V> newTaskFor(Callable<V> task) { if (aes == null) return new FutureTask<V>(task); else //調用的我們線程池的newTaskFor方法包裝任務 return aes.newTaskFor(task); } private RunnableFuture<V> newTaskFor(Runnable task, V result) { if (aes == null) return new FutureTask<V>(task, result); else //調用的我們線程池的newTaskFor方法包裝任務 return aes.newTaskFor(task, result); } //構造方法 public ExecutorCompletionService(Executor executor) { if (executor == null) throw new NullPointerException(); this.executor = executor; this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null; this.completionQueue = new LinkedBlockingQueue<Future<V>>(); } //構造方法 可以可以自己設置completionQueue public ExecutorCompletionService(Executor executor, BlockingQueue<Future<V>> completionQueue) { if (executor == null || completionQueue == null) throw new NullPointerException(); this.executor = executor; this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null; this.completionQueue = completionQueue; } public Future<V> submit(Callable<V> task) { if (task == null) throw new NullPointerException(); RunnableFuture<V> f = newTaskFor(task); //最終還是委託給真正的線程池 executor.execute(new java.util.concurrent.ExecutorCompletionService.QueueingFuture(f)); return f; } public Future<V> submit(Runnable task, V result) { if (task == null) throw new NullPointerException(); RunnableFuture<V> f = newTaskFor(task, result); //最終還是委託給真正的線程池 executor.execute(new java.util.concurrent.ExecutorCompletionService.QueueingFuture(f)); return f; } public Future<V> take() throws InterruptedException { //返回任務結果 return completionQueue.take(); } public Future<V> poll() { //返回任務結果 return completionQueue.poll(); } public Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException { //返回任務結果 return completionQueue.poll(timeout, unit); } }