お知らせ
2023.12.5(Tue)
こんにちは。ぐっさんです。
Webシステムにおいて、パフォーマンスというのは、エンジニアにとって悩みの種だと思います。
そこで、今回ご紹介するのがCallableクラスを使った並列処理です。
だいぶ昔からJavaで用意されていますが、こちらを利用することで、複数の処理を並列して実行することができます。
10個の処理を5スレッドで実行したサンプルは、下記の通りです。
package jp.amg_solution.blog.sample.callable;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CallableSample {
public static void main(String[] args) {
System.out.println("CallableSample start.");
// 1.Executorクラスの生成:引数にスレッド数を渡す。
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i=0; i<10; i++) {
// 2.Callableクラスのcallメソッドを実装して、Taskリストに登録
executorService.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Date now = new Date();
System.out.println(now + " [THREAD_ID] " + Thread.currentThread().getId());
Thread.sleep(2000);
return true;
}
});
}
// 3.実行サービスを終了
executorService.shutdown();
System.out.println("CallableSample end.");
return;
}
}
実行結果は、下記の通りです。
>java jp.amg_solution.blog.sample.callable.CallableSample CallableSample start. CallableSample end. Thu Oct 01 19:36:14 JST 2015 [THREAD_ID] 11 Thu Oct 01 19:36:14 JST 2015 [THREAD_ID] 9 Thu Oct 01 19:36:14 JST 2015 [THREAD_ID] 12 Thu Oct 01 19:36:14 JST 2015 [THREAD_ID] 10 Thu Oct 01 19:36:14 JST 2015 [THREAD_ID] 13 Thu Oct 01 19:36:16 JST 2015 [THREAD_ID] 13 Thu Oct 01 19:36:16 JST 2015 [THREAD_ID] 9 Thu Oct 01 19:36:16 JST 2015 [THREAD_ID] 12 Thu Oct 01 19:36:16 JST 2015 [THREAD_ID] 10 Thu Oct 01 19:36:16 JST 2015 [THREAD_ID] 11
スレッド処理を待ってから、処理を実行したい場合もあると思います。
その時は、Taskリストを用意することで、処理を待つことができます。
スレッド処理を待つサンプルは、下記の通りです。
package jp.amg_solution.blog.sample.callable;
import java.util.ArrayList;
import java.util.Date;
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;
public class CallableSample {
public static void main(String[] args) {
System.out.println("CallableSample start.");
// Executorクラスの生成:引数にスレッド数を渡す。
ExecutorService executorService = Executors.newFixedThreadPool(5);
// 各スレッドの処理を待つためのTaskリストを用意
List<Future<Boolean>> submitTaskList = new ArrayList<Future<Boolean>>();
for (int i=0; i<10; i++) {
// 2.Callableクラスのcallメソッドを実装して、Taskリストに登録
submitTaskList.add(executorService.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Date now = new Date();
System.out.println(now + " [THREAD_ID] " + Thread.currentThread().getId());
Thread.sleep(2000);
return true;
}
}));
}
// 3.スレッド処理を待つ
try {
for (Future<Boolean> future : submitTaskList) {
if (future.get() == false) {
throw new RuntimeException("スレッド処理エラー");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 4.実行サービスを終了
executorService.shutdown();
System.out.println("CallableSample end.");
return;
}
}
実行結果は、下記の通りです。
>java jp.amg_solution.blog.sample.callable.CallableSample CallableSample start. Thu Oct 01 19:31:33 JST 2015 [THREAD_ID] 13 Thu Oct 01 19:31:33 JST 2015 [THREAD_ID] 9 Thu Oct 01 19:31:33 JST 2015 [THREAD_ID] 12 Thu Oct 01 19:31:33 JST 2015 [THREAD_ID] 10 Thu Oct 01 19:31:33 JST 2015 [THREAD_ID] 11 Thu Oct 01 19:31:35 JST 2015 [THREAD_ID] 9 Thu Oct 01 19:31:35 JST 2015 [THREAD_ID] 12 Thu Oct 01 19:31:35 JST 2015 [THREAD_ID] 13 Thu Oct 01 19:31:35 JST 2015 [THREAD_ID] 11 Thu Oct 01 19:31:35 JST 2015 [THREAD_ID] 10 CallableSample end.
パフォーマンスチューニングを行う際の1つの手段として、並列処理は有効です。
また、試してみたい方は、サンプルプログラムをブログ内でコピーできますので、試してみてください。
よいパフォーマンスチューニングライフを!