【问题标题】:Best way for main/calling thread to wait for other threads to complete their tasks: Thread.sleep(), Latch, CompletableFuture, or something else?主/调用线程等待其他线程完成其任务的最佳方式:Thread.sleep()、Latch、CompletableFuture 还是其他?
【发布时间】:2021-01-28 17:36:39
【问题描述】:

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

选项 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.sleep() 对线程同步毫无用处。如果您发现自己将它用于此目的,那么您做错了什么。句号。
  • 不要以如图所示的显式方式使用线程。由于 Java 5 中并发框架的到来,使用它比手动使用线程更受青睐。
  • @AndrewHenle 是对的,不要使用 sleep()。您可以改为 .join() 两个线程。如果您必须等待某些线程完成/完成(run() 结束),.join() 就是设计的。顺便说一句,它也使HB边缘。 CountDownLatch 适用于分步场景。您的示例也可以,但是在更复杂的业务逻辑中,在线程中执行,只需确保在任何情况下都调用了latch.countDown()(例如,使用 finally 部分)。至于 CompletableFuture,我会将它们用于一些非常短暂的工作。对于一项特定的长期工作,我更喜欢使用明确的线程。

标签: java multithreading java-threads


【解决方案1】:

使用Thread.join():

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2020-09-21
    • 1970-01-01
    • 2023-03-07
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多