主线程/调用线程等待其他线程完成任务的最佳方式:Thread.sleep()、Latch、CompletableFuture 或其他什么?

问题描述

主线程/调用线程等待其他线程完成任务的最佳方式是什么?我想出了两个选择;可能还有更多。

选项 1 - Thread.sleep()

new Thread(() -> System.out.println("Executed task 1")).start();
new Thread(() -> System.out.println("Executed task 2")).start();
Thread.sleep(1000);

选项 2 - 闩锁

CountDownLatch latch = new CountDownLatch(2);

new Thread(() -> {
        System.out.println("Executed task 1");
        latch.countDown();
    }).start();

new Thread(() -> {
         System.out.println("Executed task 2");
         latch.countDown();
     }).start();

latch.await(1,TimeUnit.SECONDS);

选项 3 - CompletableFuture

CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> System.out.println("Executed task 1"));
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> System.out.println("Executed task 2"));
CompletableFuture.allOf(future1,future2).join();

选项 4 - ??

解决方法

使用Thread.join()

Thread t1 = new Thread(...);
Thread t2 = new Thread(...);

t1.start();
t2.start();

t1.join();
t2.join();

使用 Thread.sleep 的问题是,希望很明显,不能保证线程已经完成;但如果线程立即完成,它也可能等待长达 1 秒的时间。

但是还有一个更重要的问题,就是你在使用的时候并没有得到内存一致性的保证:无法保证线程中完成的工作在休眠后对等待线程可见。

>

您确实可以通过使用 join()await(...) 获得内存一致性保证。