【问题标题】:What is the proper way to start worker threads and then join them?启动工作线程然后加入它们的正确方法是什么?
【发布时间】:2016-02-08 21:11:49
【问题描述】:

Java 的一个教程给出了这个关于线程的例子。下面的代码 sn-p 来自https://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html。这是我要询问的部分(有一些小的修改):

Thread t = new Thread(new MessageLoop());
t.start();

while (t.isAlive()) {
    t.join();
}

主要问题是:当 t.isAlive() 在线程实际启动之前返回 false 时会发生什么?从我运行的一些测试中:

Thread t = new Thread(new Whatever());
t.start();
System.out.println(t.isAlive()+" "+t.getState());

t.getState() 可能是 NEW 而 t.isAlive() 是假的。上面的 while 循环永远不会加入我的工作线程,因为 isAlive 会返回 false(即使工作线程甚至没有启动)。除了第一个代码块中显示的方法之外,还有更好的方法来加入工作线程吗?我应该检查状态以及它是否还活着吗?可能是这样的:

while(t.isAlive() || t.getState()==Thread.State.NEW){ ... }

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    Effective Java 建议不要直接使用Thread,而是使用java.util.concurrent 包中定义的执行器框架。在此框架中,您将从Executors 中的静态工厂方法之一获取ExecutorService 开始,将new Threadt.start() 替换为对submit() 的调用,然后在线程之间使用CountDownLatch 或其他提供的同步器类,或者(在您的简单情况下)在 submit() 返回的 Future 上调用 get()

    请注意,ExecutorService 一旦创建,将永远运行,如果您忽略调用 shutdown(),可能会阻止您的程序终止。它们被设计为可重用,将许多不同的任务提交给单个任务(这可能会在内部将它们拆分为许多不同的线程),并且将继续运行,直到您告诉它们不会再发生重用。

    【讨论】:

      猜你喜欢
      • 2013-03-24
      • 2010-11-24
      • 2021-09-18
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-12
      相关资源
      最近更新 更多