JavaでExecutorServiceを使用して並列処理・逐次処理をする
並列処理
並列処理を行う場合newFixedThreadPoolメソッドでインスタンスを作成します。引数で並列処理数を設定します。
以下、5つの処理を5つのスレッドで実行します。Futureオブジェクトで同期しています。
package jp.co.confrage; import java.util.LinkedList; 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; import java.util.concurrent.TimeUnit; public class ExecutorSample { static int TASK_COUNT = 5; static int POOL_SIZE = 5; public static void main(String... args) throws InterruptedException, ExecutionException { ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE); List<Callable<String>> tasks = new LinkedList<Callable<String>>(); for (int i = 0; i < TASK_COUNT; i++) { tasks.add(new Task(i)); } try { List<Future<String>> futures = executor.invokeAll(tasks); // 実行 for (int i = 0; i < TASK_COUNT; i++) { String result = (futures.get(i)).get(); System.out.println(result); } } finally { if (!executor.isShutdown()) executor.shutdown(); if (!executor.isTerminated()) executor.awaitTermination(1, TimeUnit.MINUTES); } } } class Task implements Callable<String> { private int number; /** コンストラクタ */ public Task(int number) { this.number = number; } /** * 重い処理 * * @return レスポンス * @see java.util.concurrent.Callable#call() */ @Override public String call() throws Exception { if (this.number == 0) { Thread.sleep(2000); // 2秒かかる } else { Thread.sleep(5000); // 5秒かかる } return number + " : OK"; } }
結果は以下のようになります。
0 : OK 1 : OK 2 : OK 3 : OK 4 : OK ★約5秒強
逐次処理
逐次処理を行う場合はnewSingleThreadExecutorメソッドでインスタンスを作成します。引数はありません。1つのスレッドで処理を行います。
package jp.co.confrage; import java.util.LinkedList; 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; import java.util.concurrent.TimeUnit; public class ExecutorSample { static int TASK_COUNT = 5; public static void main(String... args) throws InterruptedException, ExecutionException { ExecutorService executor = Executors.newSingleThreadExecutor(); List<Callable<String>> tasks = new LinkedList<Callable<String>>(); for (int i = 0; i < TASK_COUNT; i++) { tasks.add(new Task(i)); } try { List<Future<String>> futures = executor.invokeAll(tasks); // 実行 for (int i = 0; i < TASK_COUNT; i++) { String result = (futures.get(i)).get(); System.out.println(result); } } finally { if (!executor.isShutdown()) executor.shutdown(); if (!executor.isTerminated()) executor.awaitTermination(1, TimeUnit.MINUTES); } } } class Task implements Callable<String> { private int number; /** コンストラクタ */ public Task(int number) { this.number = number; } /** * 重い処理 * * @return レスポンス * @see java.util.concurrent.Callable#call() */ @Override public String call() throws Exception { if (this.number == 0) { Thread.sleep(2000); // 2秒かかる } else { Thread.sleep(5000); // 5秒かかる } return number + " : OK"; } }
結果は以下のようになります。
0 : OK 1 : OK 2 : OK 3 : OK 4 : OK ★約22秒強
リストに詰めた処理順に順次実行されます。前の処理が終わるまで後続の処理は待ちます。
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント