【问题标题】:Run multiple thread at a same time then run main thread同时运行多个线程然后运行主线程
【发布时间】:2013-08-13 18:27:24
【问题描述】:

我必须运行多个线程 || 并且在执行所有这些线程后主线程继续。 比如我有一个主线程和三个子线程,我需要的是

run main thread
pause main thread
run all 3 sub threads ||ly
after complition resume main thread

我创建了一个类 extends Thread 并调用所有这些线程的 start 方法,但这并没有解决我的问题。

我的代码:

for (MyThread myThread : myThreads) {
    myThread.start();
}

感谢您的帮助。

【问题讨论】:

  • 在所有三个线程上调用 join
  • @downvoter 请发表评论

标签: java multithreading


【解决方案1】:

尝试使用Thread.join();

public class ThreadDemo implements Runnable {

   public void run() {

      Thread t = Thread.currentThread();
      System.out.print(t.getName());
      //checks if this thread is alive
      System.out.println(", status = " + t.isAlive());
   }

   public static void main(String args[]) throws Exception {

      Thread t = new Thread(new ThreadDemo());
      // this will call run() function
      t.start();
      // waits for this thread to die
      t.join();
      System.out.print(t.getName());
      //checks if this thread is alive
      System.out.println(", status = " + t.isAlive());
   }
} 

输出:

Thread-0, status = true
Thread-0, status = false

这是一个stack-over-flow link 供参考。

【讨论】:

  • 链接堆栈是一种完全有效的回答方式,尤其是重复的问题(当然是)。
  • @Gusdor 不!不欢迎仅链接的答案!有些人鲁莽地标记那些,他们应该这样做。我更有耐心(通常)。
  • @Gusdor 如果这是一个重复的问题,那么您应该投票关闭或标记关闭。此外,您可以对缺乏研究的问题投反对票。
  • 如果有一个指向原始堆栈的链接而不是复制粘贴别人的答案,我会更高兴。这意味着即使我的搜索查询没有给我正确的结果,我仍然可以对对我有用的答案和原始问题本身进行投票。
  • 我同意你的看法@Gusdor,但这个答案不是从下面给出的链接中复制的。 :-)
【解决方案2】:

忘记“暂停”线程。您的日程安排应该是

  1. 在 X 线程上启动 X 操作
  2. 等待所有线程完成
  3. 处理结果(如果有)

那么你如何等待线程完成呢?你需要一个同步机制。这些通常是操作系统级别的“标志”,称为信号量,但 java 库为您提供了几种方法。你会从this series 中得到很多,尤其是part 2: Thread Synchronization

【讨论】:

  • 请不要只发布一两个链接就走开。一些代码示例会很好。链接会随着时间的推移而消失,即使它们没有消失,它们也会需要额外的点击。更不用说教程中的示例可能比提问者实际需要的要复杂得多。
  • OP 需要的是对线程进行彻底的调整。这个非常短的系列教会了我所有我需要知道的关于 java 线程、调度和同步的知识。它发布于 2002 年! 11年,没有消失。我不认为这是最终的答案(祝你好运),但照亮一个伟大的资源有其自身的价值。 “......需要额外的点击”。好伤心。我们应该把互联网放在一个带有锚点的页面上吗?一本书中的整个图书馆?
  • 或者,您实际上可以回答 OP 的问题(最好有一些解释)并将链接包含为“进一步阅读”
  • ...但正确答案(使用 Thread.join())已经给出,无需重复。进一步阅读线程对我来说似乎也是一个好主意,因为 OP 将从中受益,而不是从另一个告诉他使用 Thread.join() 的答案中受益。话虽如此,Gusdors 的回答更适合作为评论而不是答案。我过去曾因类似的事情收到过反对票。
  • @RalfH 或者,可以将其表述为附录:“除了 [Gusdor 的出色答案],我还建议阅读一些教程,例如 [Sun 的那个]”。是的。听起来确实更像是评论,但我可能会让它溜走。
【解决方案3】:

CountDownLatch 是比Thread.join 更灵活的机制。它完全符合您的要求。更喜欢 java.util.concurrent.* 而不是旧的内置 java 技术。

优点:

  1. 使用 CDL,您可以处理单个对象而不是线程束。这可以简化代码。
  2. 它有一个getCount() 方法,可以用来实现进度条。使用 joins 会复杂得多。
  3. await(long timeout, TimeUnit unit) 可以认为比 join(long millis) 更舒服

【讨论】:

  • 看来Thread#join 也完全符合 OP 的要求。 CDL 还能提供什么?它是否更准确地满足了 OP 的要求?用更少的代码行?更健壮?
  • 嗯,我认为主要区别在于这些方法之间的代码行数。对于 HelloWorld 示例,这无关紧要,但对于大型项目,它确实如此。
  • OP 的问题是使用ExecutorService 而不是CountDownLatch “真正地”解决的。
  • ExecutorService 是一个比 CDL 复杂得多的框架。无论如何,如果没有真实案例,这些都只是建议。我确信的一件事是 join 是最不合适的方式。
  • 内部可能比较复杂,但它的 API 让整个任务更简单,更不容易出错。不是说方式更灵活。
【解决方案4】:

您可以在线程上调用 join()。假设你的线程在 myThreads 中并且你不希望你的线程被中断

// ...
// create threads and start them
// ...
for (Thread t : myThreads) {
    while (t.isAlive()) {
        try {
            t.join();
        } catch (InterruptedException e) { }
    }
}

如果它应该是可中断的:

// ...
// create threads and start them
// ...
for (Thread t : myThreads)
    t.join();

【讨论】:

  • 为了使这段代码不可中断,您会费尽心思。这是一种罕见的情况,通常人们会因为意外和/或缺乏理解而使他们的代码不间断。
  • 如果要求是等待所有 3 个子线程完成,我认为最好这样做。以防万一。
  • 如果代码允许自己被中断,这个要求将是完全的,我可以说更好,满足。中断不是突然出现的,它们必须是由于明确意图中断卡住的线程而发出的。
  • 如果走可中断路线,则根本不需要t.isAlive() 检查。代码实际上非常简单:for (Thread t : threads) t.join();处理已检查的InterruptedException,这是一个令人烦恼的问题,但这是一个单独的问题。一个方法可能只是声明抛出它。
  • '你必须在线程上调用 join()。' - '不得不'?不是真的,不。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 2013-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多