【问题标题】:Multithreading - Wait for sub threads before creating a new thread - Java多线程 - 在创建新线程之前等待子线程 - Java
【发布时间】:2016-08-04 11:57:51
【问题描述】:

我正在创建“大线程”,让我们将它们命名为 A、B、C... 并将它们放入队列中。 这些“大线程”中的每一个都在其中创建子线程。 a1, a2, a3, b1, b2, b3, c1, c2, c3...

我所做的是检查 A 是否已终止,然后启动 B 等等。但是当A完成时,a1、a2、a3同时启动和运行,A变成TERMINATED。所以 B 紧随其后的是 b1、b2、b3。我不希望这种情况发生。如何检查或让 A 等待 a1、a2、b3 然后被终止?

我已经对代码进行了简化和匿名化,但基本思想是一样的:

这里是创建可运行 foo 类并将其添加到队列中的地方,仅供参考:

RunnableFooClass rc = new RunnableFooClass();
Thread t = new Thread(rc);

这是在可运行的 foo 类(“大线程”)中创建的可运行 bar 类(“子线程”)的运行方法

@Override
public void run() {
    for(int i=0; i<Constants.THREAD_NUM; i++){
         //initialize t
         t.start
    }
}

以下代码处于无限循环中:

if(jobQueue.peek().getState() == Thread.State.TERMINATED){
    try {
        jobQueue.peek().join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(jobQueue.poll().getName() + "end.");
}
if(jobQueue.peek() != null){
    jobQueue.peek().start();
    System.out.println(jobQueue.peek().getName() + "start.");
}

【问题讨论】:

  • (除了你的直接问题)在无限循环中等待线程被终止是一个糟糕的主意。而是加入它。为什么不在运行它之前把它从队列中取出呢?然后你就不需要“偷看”了——只需等待队列中的某些东西。
  • 如果jobQueue.peek().getState() == Thread.State.TERMINATED,为什么需要jobQueue.peek().join()
  • +1 @MuratK。对于移相器。 java中没有子线程。所有新线程都将创建为单独的实体。所以申请加入会很棘手。可以改用移相器。 dzone.com/articles/java-7-understanding-phaser
  • @RealSkeptic 无限循环正在检查其他内容并将新线程添加到队列中。除了这个,我还能怎么处理?

标签: java multithreading


【解决方案1】:

基本解决方案是使用CountDownLatch

在线程 A 中创建一个初始化为 THREAD_NUM 的锁存器并将其传递给每个子线程:

@Override
public void run() {
    CountDownLatch latchA = new CountDownLatch(Constants.THREAD_NUM);
    for(int i=0; i<Constants.THREAD_NUM; i++){
         RunnableFooClass rc = new RunnableFooClass(latchA);
         Thread t = new Thread(rc);
         t.start();
    }
    latchA.await(); // wait for termination of all subthreads
}

然后,在子线程的最后run()

latchA.countDown();

【讨论】:

  • +1 用于基本解决方案,但从长远来看,Phaser 更有益。 stackoverflow.com/questions/6830904/…
  • @ankidaemon 你说得对,Phaser 更先进,更灵活,但使用频率较低(根据我的经验)。就个人而言,我倾向于在足够的情况下使用简单的结构。无论如何,感谢您指出另一个问题,它有一些有趣的答案。
  • 同意@noscreenname。是的,Phaser 使用频率较低,因为我在我的组织中也没有遇到过 Phaser
  • @noscreenname 试过了,现在解决了。谢谢。谢谢大家。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 2011-05-10
相关资源
最近更新 更多