CompletableFuture を使って生成した複数スレッドを待ち合わせる。

Runnbale のタスクと Future のタスク、それぞれのサンプルコードを書いてみた。
以下、どちらもそうなのだが、
CompletableFuture allOf メソッドが可変長引数で、リスト等のコレクションを指定できないので、
しかたなく、toArray(CompletableFuture[]::new) で、配列にしてる。

Runnbale のタスクとして、生成スレッド全てを待ち合わせ

ExecutorService eservice = Executors.newFixedThreadPool(4);

// Runnbale のリスト
List<Runnable> tasks = new ArrayList<>();

IntStream.range(1, 20).boxed().forEach(i->{
    tasks.add(()->{
        try{ Thread.sleep(1000); }catch(InterruptedException e){}
        System.out.println(i + LocalDateTime.now().format(DateTimeFormatter.ofPattern("_HH:mm:ss.SSS")));
    });
});

// スレッドとして全て実行
CompletableFuture<?>[] futures = tasks.stream()
.map(task->CompletableFuture.runAsync(task, eservice))
.toArray(CompletableFuture[]::new);

System.out.println("## submit");

// 待ち合わせる
CompletableFuture.allOf(futures).join();

System.out.println("## Join !!");

// ExecutorService を終了
eservice.shutdown();

結果

## submit
4_21:45:39.049
3_21:45:39.049
2_21:45:39.049
1_21:45:39.049
7_21:45:40.069
8_21:45:40.069
5_21:45:40.069
6_21:45:40.069
10_21:45:41.071
11_21:45:41.071
9_21:45:41.071
12_21:45:41.071
13_21:45:42.074
14_21:45:42.074
15_21:45:42.074
16_21:45:42.074
18_21:45:43.076
19_21:45:43.076
17_21:45:43.076
## Join !!

Future で任意の値を結果として残すスレッドを待ち合わせる。

ExecutorService eservice = Executors.newFixedThreadPool(4);

// Future を Supplier で生成して ExecutorService を指定して、複数スレッド実行
CompletableFuture<?>[] futures = IntStream.rangeClosed(1, 20).boxed()
.map(i->CompletableFuture.supplyAsync(()->{
    try{ Thread.sleep(1000); }catch(InterruptedException e){}
    String str = Integer.toString(i) + LocalDateTime.now().format(DateTimeFormatter.ofPattern("_HH:mm:ss.SSS"));
    System.out.println(str);
    return str;
}
, eservice))
.toArray(CompletableFuture[]::new);

System.out.println("## submit");

// 待ち合わせる
CompletableFuture.allOf(futures).oin();

System.out.println("## Join !!");

// ExecutorService を終了
eservice.shutdown();

// Future::get() の結果を取り出す
Arrays.stream(futures).forEach(f->{
    try{
        System.out.println("#result# " + f.get() );
    }catch (InterruptedException e){
        e.printStackTrace();
    }catch (ExecutionException e){
        e.printStackTrace();
    }
});

結果

## submit
3_21:47:21.016
4_21:47:21.016
1_21:47:21.016
2_21:47:21.016
8_21:47:22.039
6_21:47:22.039
5_21:47:22.039
7_21:47:22.039
10_21:47:23.042
11_21:47:23.042
9_21:47:23.042
12_21:47:23.042
15_21:47:24.044
16_21:47:24.044
13_21:47:24.044
14_21:47:24.044
20_21:47:25.046
18_21:47:25.046
17_21:47:25.046
19_21:47:25.046
## Join !!
#result# 1_21:47:21.016
#result# 2_21:47:21.016
#result# 3_21:47:21.016
#result# 4_21:47:21.016
#result# 5_21:47:22.039
#result# 6_21:47:22.039
#result# 7_21:47:22.039
#result# 8_21:47:22.039
#result# 9_21:47:23.042
#result# 10_21:47:23.042
#result# 11_21:47:23.042
#result# 12_21:47:23.042
#result# 13_21:47:24.044
#result# 14_21:47:24.044
#result# 15_21:47:24.044
#result# 16_21:47:24.044
#result# 17_21:47:25.046
#result# 18_21:47:25.046
#result# 19_21:47:25.046
#result# 20_21:47:25.046