【问题标题】:Waiting for a thread to finish with .join incosistent等待线程完成但 .join 不一致
【发布时间】:2020-06-17 20:20:37
【问题描述】:

考虑这段代码:

    public class print extends Thread {

public void run() {
    Out.print("Hello");
    Out.println("World");
}
}

public class test {
public static void main (String[] args) {
    Thread t1 = new print();
    Thread t2 = new print();
    Thread t3 = new print();
    Thread t4 = new print();
    Thread t5 = new print();

    t1.start();
    t2.start();
    t3.start();
    t4.start();
    t5.start();

    try {
        t1.join();
        t2.join();
        t3.join();
        t4.join();
        t5.join();
    }catch(InterruptedException e) {
    }
}

}

目标是在下一行打印出你好,而不是世界。输出不正确,而且非常不一致,这意味着每隔几次测试它就会改变。我从未使用过线程,但我做了一些研究人员说,使用这个 .join 应该等待一个线程完成,以便下一个线程开始。我做错了什么?

谢谢!

【问题讨论】:

  • 很可能您的 PC 太快了 - 在创建线程 2 到 5 时,线程 1 可能已经完成。你要做的是告诉所有线程:“去写你好,然后写世界”。然后你等待第一个完成 - 但所有其他人都可以随时打印
  • 您可以将当前线程名称添加到输出中,然后查看所有内容:-)
  • 好的,那我怎么让其他人也等着呢?
  • 等待一个线程完成,以便下一个线程开始 你为什么会这样认为?您发布的代码连续五次调用start(),而从未调用join()

标签: java multithreading


【解决方案1】:

它说使用这个 .join 应该等待一个线程完成,以便下一个线程开始

join 不是这样做的。

join 阻塞 current 线程,直到目标线程完成。它不会对任何其他线程做任何事情。

在您的情况下,主线程将等待t1 完成,然后等待t2 等等。但它没有安排t1 相对于t2 的运行方式。特别是,它也不会延迟启动t2t2 从你说t2.start() 开始。

好的,那我该如何让其他人也等着呢?

理想情况下,您可以使用更高级别的结构,例如工作队列和执行器服务,而不是使用低级线程原语。

如果您确实想继续这样做,请查看ReentrantLockCountDownLatch。或者让t1 打电话给t2.join()

我可能会使用CountDownLatch。将闩锁设置为需要五张票,然后您的每个线程可以打印第一行,然后在闩锁处阻塞,并且只有当闩锁释放时(这发生在所有五个票都到达时),它们才会继续打印第二行.

另外请注意,如果您想一个接一个地按顺序运行这些任务,则根本不需要多个线程。只需在同一线程上执行t1.run(); t2.run(); t3.run();

【讨论】:

  • 好的,那么我该如何安排它们呢?我需要同步它们吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 2015-08-29
  • 2011-06-09
  • 2010-10-16
相关资源
最近更新 更多