お知らせ
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つの手段として、並列処理は有効です。
また、試してみたい方は、サンプルプログラムをブログ内でコピーできますので、試してみてください。
よいパフォーマンスチューニングライフを!