Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-如何告知所有子线程都已完成_Java_Multithreading_Java 8_Runnable - Fatal编程技术网

Java-如何告知所有子线程都已完成

Java-如何告知所有子线程都已完成,java,multithreading,java-8,runnable,Java,Multithreading,Java 8,Runnable,我想同时运行几个任务,因此我有一个如下代码: for(final Task task : tasks){ (new Thread(){public void run(){ task.run(args); }}).start(); 我如何知道所有任务何时完成(任务的数量可能会有所不同),以便我只能在完成所有任务后才能运行某些东西 System.out.println("All tasks are finished"); 创建每个线程时,只需将其添加到列表中: Linke

我想同时运行几个任务,因此我有一个如下代码:

for(final Task task : tasks){
    (new Thread(){public void run(){
        task.run(args);
}}).start();
我如何知道所有任务何时完成(任务的数量可能会有所不同),以便我只能在完成所有任务后才能运行某些东西

System.out.println("All tasks are finished");

创建每个线程时,只需将其添加到列表中:

LinkedList<Thread> threads = new LinkedList<>();
然后,您可以检查列表中的每个线程,查看它是否已完成:

boolean allFinished = true;

for (Thread t : threads) {
 if (t.isAlive()) {
  allFinished = false;
  break;
 }
}
有关检查线程是否完成的更多信息,请参阅此链接:

boolean allFinished = true;

for (Thread t : threads) {
 if (t.isAlive()) {
  allFinished = false;
  break;
 }
}


这个问题的关键是,如果您想稍后检查线程,您必须在某处存储线程列表(或数组等)。

不要显式创建线程,而是将您的可运行程序提交给ExecutorService,然后调用其和方法:


另一种方法是使用。这样做可以为您提供一些其他漂亮的特性。有关一些示例,请参见

您还可以使用倒计时闩锁来指示线程是否已完成。看

像这样:

public static class Task {
    void run(String args[]) {
        System.out.println("Hello");
    }
}

public static void main(String[] args) {
    List<Task> tasks = Arrays.asList(new Task(), new Task(), new Task());
    CountDownLatch doneSignal = new CountDownLatch(tasks.size());

    for(final Task task : tasks) {
        (new Thread() {
            public void run(){
                task.run(args);
            }
        }).start();
        doneSignal.countDown();  //counts latch down by one
    }

    //A
    new Thread() {
        public void run() {
            try {
                doneSignal.await(); //blocks until latch counted down to zero
                System.out.println("All tasks completed");
            } catch(Exception e) {
                System.out.println("Warning: Thread interrupted.");
            }
        }
    }.start();
}
公共静态类任务{
无效运行(字符串参数[]){
System.out.println(“你好”);
}
}
公共静态void main(字符串[]args){
List tasks=Arrays.asList(new Task(),new Task(),new Task());
CountDownLatch doneSignal=新的CountDownLatch(tasks.size());
对于(最终任务:任务){
(新线程(){
公开募捐{
task.run(args);
}
}).start();
doneSignal.countDown();//按1计算闩锁关闭次数
}
//A
新线程(){
公开募捐{
试一试{
doneSignal.await();//阻塞,直到闩锁计数为零
System.out.println(“所有任务已完成”);
}捕获(例外e){
System.out.println(“警告:线程中断”);
}
}
}.start();
}

每个任务线程在完成时都会将闩锁向下计数一次。在//A处创建的线程将等待闩锁倒计时到零。只有这样,才会打印“所有任务已完成”语句。因此,doneSignal.await()之后的语句基本上只能在所有线程完成后执行。

使用CyclicBarrier,例如:
较短的版本是使用并行流

tasks.parallelStream().forEach(t -> t.run(args));

这将使用您拥有的所有CPU(如果您有足够的任务)运行所有任务,并等待所有任务完成。

有一个
Thread.getState()
方法可以告诉您线程何时终止,但我不认为您可以使用匿名
Thread
s来执行。ExecutorService.waittermination()的工作原理类似于“Process.waitFor()”?意思是等待结束后,下面的代码将等待并自行执行?或者,如果执行结束,我还需要检查自己吗?(如其他答案中所示)@ArtemioRamirez我相信文档(我已链接到该文档)回答这个问题。我没有意识到这些是实际的链接,我的错。我认为这只是良好的格式设置。TY这是Java 7中最好的选择,但在Java 8中,我会交替使用parallelStream(0(请参见我的答案),而不是终止线程池(如果您想使用现有的线程池),您可以使用
ExecutorService.invokeAll()
并等待生成的
Future
s。我实际上使用的是Java 8,所以这是现在最好的答案。
tasks.parallelStream().forEach(t -> t.run(args));