向執行緒池提交任務的兩個方法 execute()、submit() 的區別,我總結的主要有四點
(1)申明位置不同:execute() 方法定義在 Executor 介面中,submit() 方法定義在 ExecutorService 介面中;
ExecutorService 介面繼承了 Executor 介面,
(2)可傳引數不同: execute() 方法引數只能傳入 Runnable 介面;submit() 方法有三個多載的方法;

public interface ExecutorService extends Executor {
//其他代碼
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
<T> Future<T> submit(Callable<T> task);
//其他代碼
}
(3) 有無回傳值不同:execute() 方法沒有回傳值是 void;submit() 方法用于提交需要回傳值的任務,
執行緒池會回傳一個 future 型別的物件,通過這個 future物件可以判斷任務是否執行成功,
并且可以通過future的 get() 方法來獲取回傳值,get() 方法會阻塞當前執行緒直到任務完成,
而使用 get(long timeout,TimeUnit unit)方法則會阻塞當前執行緒一段時間后立即回傳,
這時候有可能任務都還沒有執行完就回傳的,時間一到就會回傳當前的結果,
(4) 如果我們希望呼叫者能夠知道內部有 Exception 并做處理,那么就需要實作 Callable 介面,并且通過對
Future.get() 進行拋出例外的捕獲,然后對其進行處理,
演示第(4)點的代碼:
package com.dai.test;
import java.util.concurrent.*;
public class ThreadPoolTest implements Callable {
@Override
public Integer call() {
System.out.println("開始執行call...");
System.out.println(1 / 0);
System.out.println("報錯就不會執行這了");
return 1;
}
public static void main(String[] args) {
ExecutorService pool = new ThreadPoolExecutor(//1、核心執行緒 2、最大執行緒
3, 3, 0, TimeUnit.SECONDS,//3、空閑等待時間 4、等待時間單位
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),//5、等待佇列 6、執行緒工廠
new ThreadPoolExecutor.AbortPolicy());//7、拒絕策略
FutureTask<Integer> task = new FutureTask<>(new ThreadPoolTest());
pool.submit(task);//execute()提交也會列印錯誤資訊
try {
Integer integer = task.get(); //假如不呼叫get() 就不會有任務錯誤資訊
System.out.println(integer);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
pool.shutdown();//停止接受任務,已提交的任務還是會繼續執行完
}
}
執行列印結果:
開始執行call...
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.dai.test.ThreadPoolTest.main(ThreadPoolTest.java:23)
Caused by: java.lang.ArithmeticException: / by zero
at com.dai.test.ThreadPoolTest.call(ThreadPoolTest.java:10)
at com.dai.test.ThreadPoolTest.call(ThreadPoolTest.java:5)
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:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
其實只要你代碼中有對回傳值明確的處理例外, execute() 、submit() 方法提交的任務都是會顯示報與之對應的錯誤的,
有用點個關注,手留余香!?? ?? ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/2848.html
標籤:其他
上一篇:從零學ELK系列(十):SpringBoot專案接入ELK升級版(超詳細圖文教程)
下一篇:你說啥什么?注解你還不會?
