package java.util.concurrent; import java.util.List; import java.util.Collection; public interface ExecutorService extends Executor { //啓動一次順序關閉,執行之前提交的任務,但不接受新任務 void shutdown(); //試圖中止全部正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的任務列表 List<Runnable> shutdownNow(); //若是此執行程序已關閉,則返回 true boolean isShutdown(); //若是關閉後全部任務都已完成,則返回 true boolean isTerminated(); //阻塞當前線程:直到全部任務執行完畢、等待超時或者當前線程中斷,纔會返回 boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; //提交一個返回值的任務用於執行,返回一個表示任務的未決結果的 Future <T> Future<T> submit(Callable<T> task); //提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future Future<?> submit(Runnable task); //提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future <T> Future<T> submit(Runnable task, T result); //執行給定的任務,當全部任務完成時,返回保持任務狀態和結果的 Future 列表 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; // 執行給定的任務,當全部任務完成或超時期滿時(不管哪一個首先發生),返回保持任務狀態和結果的 Future 列表 <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; //執行給定的任務,若是在給定的超時期滿前某個任務已成功完成(也就是未拋出異常),則返回其結果 <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
父接口:html
Executorjava
已知子接口:api
已知實現類:多線程
AbstractExecutorService, ScheduledThreadPoolExecutor, ThreadPoolExecutor閉包
Executors
類提供了用於此包中所提供的執行程序服務的工廠方法。app
提供兩個方法來關閉 ExecutorService:ide
shutdown()
方法在終止前容許執行之前提交的任務;沒法提交新任務。this
shutdownNow()
方法阻止等待任務啓動並試圖中止當前正在執行的任務。沒有任務在等待執行,而且沒法提交新任務,執行中的任務將會收到中斷信號。spa
從父接口,繼承獲得的 execute(Runnable command) 方法,只能執行Runnable類型的線程,並且還不能獲得返回值。在ExecutorService 中 submit() 經過返回一個可獲取返回值的 Future,不只支持了執行Runnable類型的線程,也支持了Callable的線程執行。
invokeAny() 和 invokeAll() 是批量執行的最經常使用形式,它們執行任務 collection,而後等待至少一個,或所有任務完成(可以使用 ExecutorCompletionService
類來編寫這些方法的自定義變體)。
例如,AbstractExecutorService中invokeAny(Collection<? extends Callable<T>> tasks):
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { try { return doInvokeAny(tasks, false, 0);//執行上述的私有方法 } catch (TimeoutException cannotHappen) { assert false; return null; } }
其中的doInvokeAny方法:
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(); List<Future<T>> futures= new ArrayList<Future<T>>(ntasks); // ExecutorCompletionService負責執行任務,後面調用用poll返回第一個執行結果 ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this); // 這裏出於效率的考慮,每次提交一個任務以後,就檢查一下有沒有執行完成的任務 try { ExecutionException ee = null; long lastTime = timed ? System.nanoTime() : 0; Iterator<? extends Callable<T>> it = tasks.iterator(); // 先提交一個任務 futures.add(ecs.submit(it.next())); --ntasks; int active = 1; for (;;) { // 嘗試獲取有沒有執行結果(這個結果是馬上返回的) Future<T> f = ecs.poll(); // 沒有執行結果 if (f == null) { // 若是還有任務沒有被提交執行的,就再提交一個任務 if (ntasks > 0) { --ntasks; futures.add(ecs.submit(it.next())); ++active; } // 沒有任務在執行了,並且沒有拿到一個成功的結果。 else if (active == 0) break; // 若是設置了超時狀況 else if (timed) { // 等待執行結果直到有結果或者超時 f = ecs.poll(nanos, TimeUnit.NANOSECONDS); if (f == null) throw new TimeoutException(); // 這裏的更新不可少,由於這個Future多是執行失敗的狀況,那麼還須要再次等待下一個結果,超時的設置仍是須要用到。 long now = System.nanoTime(); nanos -= now - lastTime; lastTime = now; } // 沒有設置超時,而且全部任務都被提交了,則一直等到第一個執行結果出來 else f = ecs.take(); } // 有返回結果了,嘗試從future中獲取結果,若是失敗了,那麼須要接着等待下一個執行結果 if (f != null) { --active; try { return f.get(); } catch (ExecutionException eex) { ee = eex; } catch (RuntimeException rex) { ee = new ExecutionException(rex); } } } // ExecutorCompletionService執行時發生錯誤返回了全是null的future if (ee == null) ee = new ExecutionException(); throw ee; } finally { // 嘗試取消全部的任務(對於已經完成的任務沒有影響) for (Future<T> f : futures) f.cancel(true); } }
當全部的任務被提交後,任務執行返回的Future會被依次添加到一個BlockingQueue中,而後找到第一個執行成功任務的方法就是從BlockingQueue取出第一個元素,這個就是doInvokeAny方法用到的ExecutorCompletionService的基本原理。
void shutdown()
啓動一次順序關閉,執行之前提交的任務,但不接受新任務。若是已經關閉,則調用沒有其餘做用。
拋出:
SecurityException
- 若是安全管理器存在而且關閉,此 ExecutorService 可能操做某些不容許調用者修改的線程(由於它沒有保持 RuntimePermission
("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。
List<Runnable> shutdownNow()
試圖中止全部正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的任務列表。
沒法保證可以中止正在處理的活動執行任務,可是會盡力嘗試。例如,經過 Thread.interrupt()
來取消典型的實現,因此沒法響應中斷的任務可能將永遠沒法終止。
返回:
從未開始執行的任務的列表
拋出:
SecurityException
- 若是安全管理器存在而且關閉,此 ExecutorService 可能操做某些不容許調用者修改的線程(由於它沒有保持 RuntimePermission
("modifyThread")),或者安全管理器的 checkAccess 方法拒絕訪問。
boolean isShutdown()
若是此執行程序已關閉,則返回 true。
返回:
若是此執行程序已關閉,則返回 true
boolean isTerminated()
若是關閉後全部任務都已完成,則返回 true。注意,除非首先調用 shutdown 或 shutdownNow,不然 isTerminated 永不爲 true。
返回:
若是關閉後全部任務都已完成,則返回 true
boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedException
阻塞當前線程:直到全部任務執行完畢、等待超時或者當前線程中斷,纔會返回。
通常在調用shutdown()方法後調用,用來檢測 timeout 時間後線程池是否關閉。
參數:
timeout
- 最長等待時間
unit
- timeout 參數的時間單位
返回:
若是此執行程序終止,則返回 true;若是終止前超時期滿,則返回 false
拋出:
InterruptedException
- 若是等待時發生中斷
<T> Future<T> submit(Callable<T> task)
提交一個返回值的任務用於執行,返回一個表示任務的未決結果的 Future。該 Future 的 get 方法在成功完成時將會返回該任務的結果。
若是想當即阻塞任務的等待,則可使用 result = exec.submit(aCallable).get(); 形式的構造。
注:Executors
類包括了一組方法,能夠轉換某些其餘常見的相似於閉包的對象,例如,將 PrivilegedAction
轉換爲 Callable
形式,這樣就能夠提交它們了。
參數:
task
- 要提交的任務
返回:
表示任務等待完成的 Future
拋出:
RejectedExecutionException
- 若是任務沒法安排執行
NullPointerException
- 若是該任務爲 null
<T> Future<T> submit(Runnable task, T result)
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在成功完成時將會返回給定的結果。
參數:
task
- 要提交的任務
result
- 返回的結果
返回:
表示任務等待完成的 Future
拋出:
RejectedExecutionException
- 若是任務沒法安排執行
NullPointerException
- 若是該任務爲 null
Future<?> submit(Runnable task)
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。該 Future 的 get 方法在 成功 完成時將會返回 null。
參數:
task
- 要提交的任務
返回:
表示任務等待完成的 Future
拋出:
RejectedExecutionException
- 若是任務沒法安排執行
NullPointerException
- 若是該任務爲 null
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException
執行給定的任務,當全部任務完成時,返回保持任務狀態和結果的 Future 列表。返回列表的全部元素的 Future.isDone()
爲 true。注意,能夠正常地或經過拋出異常來終止 已完成 任務。若是正在進行此操做時修改了給定的 collection,則此方法的結果是不肯定的。
參數:
tasks
- 任務 collection
返回:
表示任務的 Future 列表,列表順序與給定任務列表的迭代器所生成的順序相同,每一個任務都已完成。
拋出:
InterruptedException
- 若是等待時發生中斷,在這種狀況下取消還沒有完成的任務。
NullPointerException
- 若是任務或其任意元素爲 null
RejectedExecutionException
- 若是全部任務都沒法安排執行
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout,TimeUnit unit) throws InterruptedException
執行給定的任務,當全部任務完成或超時期滿時(不管哪一個首先發生),返回保持任務狀態和結果的 Future 列表。返回列表的全部元素的 Future.isDone()
爲 true。一旦返回後,即取消還沒有完成的任務。注意,能夠正常地或經過拋出異常來終止 已完成 任務。若是此操做正在進行時修改了給定的 collection,則此方法的結果是不肯定的。
參數:
tasks
- 任務 collection
timeout
- 最長等待時間
unit
- timeout 參數的時間單位
返回:
表示任務的 Future 列表,列表順序與給定任務列表的迭代器所生成的順序相同。若是操做未超時,則已完成全部任務。若是確實超時了,則某些任務還沒有完成。
拋出:
InterruptedException
- 若是等待時發生中斷,在這種狀況下取消還沒有完成的任務
NullPointerException
- 若是任務或其任意元素或 unit 爲 null
RejectedExecutionException
- 若是全部任務都沒法安排執行
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException,ExecutionException
執行給定的任務,若是某個任務已成功完成(也就是未拋出異常),則返回其結果。一旦正常或異常返回後,則取消還沒有完成的任務。若是此操做正在進行時修改了給定的 collection,則此方法的結果是不肯定的。
參數:
tasks
- 任務 collection
返回:
某個任務返回的結果
拋出:
InterruptedException
- 若是等待時發生中斷
NullPointerException
- 若是任務或其任意元素爲 null
IllegalArgumentException
- 若是任務爲空
ExecutionException
- 若是沒有任務成功完成
RejectedExecutionException
- 若是任務沒法安排執行
<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout,TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException
執行給定的任務,若是在給定的超時期滿前某個任務已成功完成(也就是未拋出異常),則返回其結果。一旦正常或異常返回後,則取消還沒有完成的任務。若是此操做正在進行時修改了給定的 collection,則此方法的結果是不肯定的。
參數:
tasks
- 任務 collection
timeout
- 最長等待時間
unit
- timeout 參數的時間單位
返回:
某個任務返回的結果
拋出:
InterruptedException
- 若是等待時發生中斷
NullPointerException
- 若是任務或其任意元素或 unit 爲 null
TimeoutException
- 若是在全部任務成功完成以前給定的超時期滿
ExecutionException
- 若是沒有任務成功完成
RejectedExecutionException
- 若是任務沒法安排執行
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a){ this.a=a; } @Override public String call(){ System.out.println("當前值爲:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { List<Future<String>> futures = executorService.invokeAll(list); for (Future<String> future : futures) { System.out.println("返回值:"+future.get()); } } catch (InterruptedException e) {//invokeAll 可能拋出的異常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能拋出的異常 e.printStackTrace(); } executorService.shutdown(); } }
運行結果:
當前值爲:0
當前值爲:2
當前值爲:3
當前值爲:4
當前值爲:1
返回值:0
返回值:1
返回值:2
返回值:3
返回值:4
若是在call方法中拋出異常了,只有在main方法調用了future.get(),main線程才能捕獲到異常:
1.不調用future.get():
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call(){ System.out.println("當前值爲:" + a); if (a == 2) { throw new RuntimeException(); } return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { executorService.invokeAll(list); } catch (InterruptedException e) {//invokeAll 可能拋出的異常 e.printStackTrace(); } executorService.shutdown(); } }
運行結果:
當前值爲:0
當前值爲:1
當前值爲:3
當前值爲:4
當前值爲:2
調用 future.get():
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call(){ System.out.println("當前值爲:" + a); if (a == 2) { throw new RuntimeException(); } return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { List<Future<String>> futures = executorService.invokeAll(list); for (Future<String> future : futures) { System.out.println("返回值:" + future.get()); } } catch (InterruptedException e) {//invokeAll 可能拋出的異常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能拋出的異常 e.printStackTrace(); } executorService.shutdown(); } }
運行結果:
當前值爲:0
當前值爲:2
當前值爲:1
當前值爲:4
當前值爲:3
返回值:0
返回值:1
java.util.concurrent.ExecutionException: java.lang.RuntimeException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.thread.InvokeAllTest.main(InvokeAllTest.java:37)
Caused by: java.lang.RuntimeException
at com.thread.InvokeAllTest.call(InvokeAllTest.java:22)
at com.thread.InvokeAllTest.call(InvokeAllTest.java:11)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
將上述例子:
executorService.invokeAll(list);
修改成:
executorService.invokeAll(list, 15, TimeUnit.SECONDS);
若在call()中有異常拋出,只有在main方法調用了future.get(),main線程才能捕獲到異常。
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call() { System.out.println("當前值爲:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { String value = executorService.invokeAny(list); System.out.println("最後結果值是======:" + value); } catch (InterruptedException e) {//invokeAll 可能拋出的異常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能拋出的異常 e.printStackTrace(); } executorService.shutdown(); } }
運行結果:
當前值爲:0
當前值爲:2
當前值爲:3
當前值爲:1
最後結果值是======:0
當前值爲:4
invokeAny取得了某一個線程返回的值以後,可是其餘線程仍將繼續運行,直到運行結束。
若是任意一個任務在call()拋出了異常,而且異常沒有在call()中被顯示捕獲處理,那麼控制檯將不會打印任何異常信息。
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call() throws Exception{ if (a>0) { throw new Exception("error"); } System.out.println("當前值爲:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { String value = executorService.invokeAny(list); System.out.println("最後結果值是======:" + value); } catch (InterruptedException e) {//invokeAll 可能拋出的異常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能拋出的異常 e.printStackTrace(); } executorService.shutdown(); } }
運行結果:
當前值爲:0
最後結果值是======:0
若全部的任務都發生異常,那麼將返回最後一個異常而且輸出異常信息,最終在ExecutionException中被捕獲:
package com.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InvokeAllTest implements Callable<String> { int a = 0; public InvokeAllTest(int a) { this.a = a; } @Override public String call() throws Exception{ if (a>-1) { throw new Exception("error"); } System.out.println("當前值爲:" + a); return Integer.toString(a); } public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(3); List<Callable<String>> list = new ArrayList<>(); for (int i = 0; i < 5; i++) { list.add(new InvokeAllTest(i)); } try { String value = executorService.invokeAny(list); System.out.println("最後結果值是======:" + value); } catch (InterruptedException e) {//invokeAll 可能拋出的異常 e.printStackTrace(); } catch (ExecutionException e) {//future.get() 可能拋出的異常 e.printStackTrace(); } executorService.shutdown(); } }
運行結果:
java.util.concurrent.ExecutionException: java.lang.Exception: error
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at java.util.concurrent.AbstractExecutorService.doInvokeAny(AbstractExecutorService.java:193)
at java.util.concurrent.AbstractExecutorService.invokeAny(AbstractExecutorService.java:215)
at com.thread.InvokeAllTest.main(InvokeAllTest.java:33)
Caused by: java.lang.Exception: error
at com.thread.InvokeAllTest.call(InvokeAllTest.java:20)
at com.thread.InvokeAllTest.call(InvokeAllTest.java:10)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
將上述例子:
executorService.invokeAny(list);
修改成:
executorService.invokeAny(list, 15, TimeUnit.SECONDS);
Executor接口很是單一,就是執行一個Runnable的命令。
public interface Executor { void execute(Runnable command); }
ExecutorService接口擴展了Executor接口,增長狀態控制,執行多個任務返回Future。
關於狀態控制的方法:
// 發出關閉信號,不會等到現有任務執行完成再返回,可是現有任務仍是會繼續執行, // 能夠調用awaitTermination等待全部任務執行。再也不接受新的任務。 void shutdown(); // 馬上關閉,嘗試取消正在執行的任務(不保證會取消成功),返回未被執行的任務 List<Runnable> shutdownNow(); // 是否發出關閉信號 boolean isShutdown(); // 是否全部任務都執行完畢在shutdown以後,也就是若是不調用shutdownNow或者 // shutdown是不可能返回true boolean isTerminated(); // 進行等待直到全部任務完成或者超時 boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
提交單個任務,馬上返回一個Future存儲任務執行的實時狀態
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
執行多個任務的方法,有兩種方式,一種等到全部任務執行完成才返回:
<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; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
經過上面的代碼能夠看出ExecutorService能夠執行兩種類型的任務:Runnable和Callable,而Callable用的更加多。二者區別很簡單,前者不會返回執行結果然後者會返回一個執行結果:
public interface Callable<V> { V call() throws Exception; }
接着說說Future,也就是執行任務的返回類型。
Future能夠當作是一張發票。好比你送件衣服到洗衣店清洗,他們會開張發票給你,你拿着發票能夠去拿回你洗好的衣服或者去洗衣店問衣服是否洗好了等等。
public interface Future<V> { //取消任務,參數mayInterruptIfRunning爲true時,若是要取消的任務正在執行, //會把執行這個任務的線程設爲中斷,爲false時,正在執行的任務會被容許執行完成 boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); //獲取執行結果,若是任務執行中,會等到任務完成再返回 V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
最後看看ScheduledExecutorService接口,該接口是ExecutorService的子接口,增長了定時執行任務的功能:
public interface ScheduledExecutorService extends ExecutorService { public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); // 等待必定時間而後開始執行一個任務,每隔period參數設置的時間 // 重複一次,(多線程執行) public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); // 等待必定時間而後開始執行一個任務,完成後,等待delay參數設置的時間 // 而後在執行一次任務。(單線程執行) public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); }