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

こんにちわ、猫好きリーマンのほげ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);
    }
}

 

解説

  1. スレッドプールの作成。とりあえず10スレッド。
  2. リクエストデータ。この順序の結果を格納する。
  3. スレッドの処理結果を格納する配列。
  4. スレッドの待ち合わせ用。
  5. スレッドの結果を格納するためのインデックス。スレッドから触れるようにIntegerで定義。
  6. スレッド呼出。
  7. 結果を③の配列に格納。
  8. 結果にnullの場合は詰める。
  9. 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/

\ 最新情報をチェック /