複数スレッドで平行処理し、順序そのままで結果を格納する

こんにちわ、猫好きリーマンのほげPGです。
今回は複数スレッドで平行処理し、要求時の順序で結果を配列に格納するコードを紹介します。
ソースコード
import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; public class Hoge { public static void main(String[] args) throws Exception { log("start ..."); ExecutorService streamPool = Executors.newFixedThreadPool(10); //① List<String> requests = Arrays.asList(new String[] {"11", "22", "33", "44", "55"}); //② String[] array = new String[requests.size()]; //③ try { CountDownLatch latch = new CountDownLatch(requests.size()); //④ int i = 0; for (String val : requests) { Integer x = i++; //⑤ streamPool.submit(() -> { //⑥ log("start..." + x); try { array[x] = doHoge(val); //⑦ } catch (Exception e) { log(e.toString()); } finally { latch.countDown(); } log("end..." + x); }); } latch.await(); } finally { streamPool.shutdown(); } List<String> results = Arrays.stream(array) .filter(pi -> pi != null) //⑧ .collect(Collectors.toList()); //⑨ log(results.toString()); log("end ..."); } static Random rand = new Random(); static String doHoge(String v) throws InterruptedException { if ("44".equals(v)) throw new RuntimeException("test"); int n = rand.nextInt(10); Thread.sleep(n * 1000); return v + "-" + n; } public static void log(String msg) { System.out.println(msg); } }
解説
- スレッドプールの作成。とりあえず10スレッド。
- リクエストデータ。この順序の結果を格納する。
- スレッドの処理結果を格納する配列。
- スレッドの待ち合わせ用。
- スレッドの結果を格納するためのインデックス。スレッドから触れるようにIntegerで定義。
- スレッド呼出。
- 結果を③の配列に格納。
- 結果にnullの場合は詰める。
- Listに変換。
ポイントはスレッドの処理結果を配列に格納し、最後にnullを除去するだけ。
今回はここまで。
◆WEB会議/セミナーシステム『Szia』
https://www.ois-yokohama.co.jp/szia/
◆サーバサイドで動作するミドルウェア『ReDois』
https://www.ois-yokohama.co.jp/redois/wp_redois/
◆AIがトレンドトピックをもとに、読まれそうな記事タイトルを自動生成『AI Title Maker』
https://ai-title.com/