Difference Between ExecutorService execute and submit in Java - Java 147

Difference Between ExecutorService execute and submit in Java – Java 147

Difference 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 MethodSubmit Method
在 Executor 宣告在 ExecutorService 宣告
只能接受 Runnable 的任務可以接受 Runnable 和 Callable 任務
傳回類型為 void 傳回類型為 Future
不關心結果,但希望程式碼由執行緒池的執行緒並行執行時關心結果,並需要來取得執行任務的結果時

發佈留言