Table of Contents
ToggleDifference Between ExecutorService execute and submit in Java
擴充了一些方法,調度管理和控制執行緒,執行異步任務,實現了 Runnable 接口 及 Callable 接口,提供 execute 方法與 submit 方法, ExecutorService execute and submit Methods in Java ,介紹 execute 及 submit 方法的區別,本篇增加了範例,並透過單元測試來驗證產出結果。
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- multithreading
| +- executorservice
| +- DifferenceExecutorServiceExecuteSubmitTest.java
單元測試
Java ExecutorService execute submit Methods 提供執行、提交等操作執行緒池。
execute
此方法會在將來的某個時間執行任務,該任務可以在新執行緒、執行緒池或調用執行緒中執行,由 Executor 實現決定,一個 void 方法,表示不傳回任何值,一旦在 execute 方法中分配了任務,將不會得到任何回應。
Java ExecutorService execute submit with Examples 建立一個執行緒池,固定數量 2 條執行緒,執行 3 個任務,每個任務耗時 1 秒完成。
@Test
public void execute() {
int poolSize = 2;
int taskSize = 3;
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
for (int i = 0; i < taskSize; i++) {
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("T[" + Thread.currentThread().getId() + "] OK");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
}
try {
executorService.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
T[11] OK
T[12] OK
T[11] OK
submit
此方法會在將來的某個時間執行任務,該任務可以在新執行緒、執行緒池或調用執行緒中執行,由 Executor 實現決定,與 execute 方法不同,此方法會傳回一個 Future ,保存異步計算的結果, Future 物件用於在執行開始後處理任務,當我們需要執行的結果時,就可以使用 Future 物件的 submit 方法,為了得到結果,可以在 Future 上使用 get 方法,傳回一個物件,如果在任務完成之前調用 get 方法,調用執行緒將阻塞直到結果準備好,並可能拋出檢查例外,或者如果任務已完成,則 Future 物件將保存傳回的結果。
Java ExecutorService execute submit with Examples 建立一個執行緒池,固定數量 2 條執行緒,執行 3 個任務,每個任務耗時 1 秒完成。
@Test
public void submit() {
int poolSize = 2;
int taskSize = 3;
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i = 0; i < taskSize; i++) {
Future<String> future = executorService.submit(() -> {
String result = null;
try {
TimeUnit.SECONDS.sleep(1);
result = "T[" + Thread.currentThread().getId() + "] OK";
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return result;
});
futures.add(future);
}
futures.forEach(e -> {
try {
String result = e.get();
System.out.println("T[" + Thread.currentThread().getId() + "]: " + result);
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
T[1]: T[11] OK
T[1]: T[12] OK
T[1]: T[11] OK
brokenSubmit
Java ExecutorService execute submit with Examples 建立一個執行緒池,固定數量 2 條執行緒,執行 3 個任務,每個任務耗時 1 秒完成,執行緒拋出例外。
@Test
public void brokenSubmit() {
int poolSize = 2;
int taskSize = 3;
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i = 0; i < taskSize; i++) {
Future<String> future = executorService.submit(() -> {
String result = null;
boolean flag = true;
if (flag) {
throw new IOException();
}
try {
TimeUnit.SECONDS.sleep(1);
result = "T[" + Thread.currentThread().getId() + "] OK";
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return result;
});
futures.add(future);
}
futures.forEach(e -> {
try {
String result = e.get();
System.out.println("T[" + Thread.currentThread().getId() + "]: " + result);
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
java.util.concurrent.ExecutionException: java.io.IOException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.ruoxue.java_147.multithreading.DifferenceExecutorServiceExecuteSubmitTest.lambda$4(DifferenceExecutorServiceExecuteSubmitTest.java:94)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.ruoxue.java_147.multithreading.DifferenceExecutorServiceExecuteSubmitTest.submitThrowException(DifferenceExecutorServiceExecuteSubmitTest.java:92)
Caused by: java.io.IOException
at org.ruoxue.java_147.multithreading.DifferenceExecutorServiceExecuteSubmitTest.lambda$3(DifferenceExecutorServiceExecuteSubmitTest.java:79)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
DifferenceExecutorServiceExecuteSubmitTest.java
ExecutorService execute submit Java 新增單元測試,驗證是否符合預期。
package org.ruoxue.java_147.multithreading.executorservice;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
public class DifferenceExecutorServiceExecuteSubmitTest {
@Test
public void execute() {
int poolSize = 2;
int taskSize = 3;
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
for (int i = 0; i < taskSize; i++) {
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("T[" + Thread.currentThread().getId() + "] OK");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
}
try {
executorService.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
@Test
public void submit() {
int poolSize = 2;
int taskSize = 3;
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i = 0; i < taskSize; i++) {
Future<String> future = executorService.submit(() -> {
String result = null;
try {
TimeUnit.SECONDS.sleep(1);
result = "T[" + Thread.currentThread().getId() + "] OK";
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return result;
});
futures.add(future);
}
futures.forEach(e -> {
try {
String result = e.get();
System.out.println("T[" + Thread.currentThread().getId() + "]: " + result);
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
@Test
public void brokenSubmit() {
int poolSize = 2;
int taskSize = 3;
ExecutorService executorService = Executors.newFixedThreadPool(poolSize);
List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i = 0; i < taskSize; i++) {
Future<String> future = executorService.submit(() -> {
String result = null;
boolean flag = true;
if (flag) {
throw new IOException();
}
try {
TimeUnit.SECONDS.sleep(1);
result = "T[" + Thread.currentThread().getId() + "] OK";
} catch (InterruptedException ex) {
ex.printStackTrace();
}
return result;
});
futures.add(future);
}
futures.forEach(e -> {
try {
String result = e.get();
System.out.println("T[" + Thread.currentThread().getId() + "]: " + result);
} catch (Exception ex) {
ex.printStackTrace();
}
});
}
}
心得分享
Java ExecutorService execute submit Methods 的區別:
Execute Method | Submit Method |
---|---|
在 Executor 宣告 | 在 ExecutorService 宣告 |
只能接受 Runnable 的任務 | 可以接受 Runnable 和 Callable 任務 |
傳回類型為 void | 傳回類型為 Future |
不關心結果,但希望程式碼由執行緒池的執行緒並行執行時 | 關心結果,並需要來取得執行任務的結果時 |