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の大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^


コメント