2016-04-21 93 views
2

我要同时运行几个任务,所以我有一个看起来像这样的代码:爪哇 - 如何告诉所有的子线程完成

for(final Task task : tasks){ 
    (new Thread(){public void run(){ 
     task.run(args); 
}}).start(); 

我怎么能知道,当所有的任务都做了(在任务数量可能会有所不同),以便我可以在完成所有工作后才能运行某些任务?

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

有一个'Thread.getState()'方法可以告诉你什么时候线程被终止了,但我不认为你可以用匿名'Thread'来做到这一点。 – NAMS

回答

5

一个较短的版本是使用parallelStream

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

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

+0

我实际上使用Java 8,所以这是现在最好的答案。 –

0

当你创建每个线程只需添加到列表:

LinkedList<Thread> threads = new LinkedList<>(); 

而当你犯了一个新的线程:

Thread t = new Thread() { 
    public void run() { 
     task.run(args); 
    } 
} 
threads.add(t); 

然后你就可以在你的列表检查每一个线程看看它是否完成:

boolean allFinished = true; 

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

查看检查,如果线程都完成这个环节更多信息:

How to know if other threads have finished?

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

5

而是明确创建线程,提交你的Runnable到一个ExecutorService,然后调用其shutdownawaitTermination方法:

ExecutorService executor = Executors.newFixedThreadPool(tasks.size()); 

for (final Task task : tasks) { 
    executor.submit(new Runnable() { 
     @Override 
     public void run() { 
      task.run(args); 
     } 
    }); 
} 

executor.shutdown(); 
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLSECONDS); 
+0

“ExecutorService.awaitTermination()”是否像“Process.waitFor()”一样工作?意思是等待结束后,下面的代码会等待并执行它自己的代码?或者如果执行结束,我还需要检查自己吗? (如在其他答案) –

+0

@ArtemioRamirez我相信文档(我已经链接)回答。 – VGR

+0

我没有意识到这些是实际的联系,我的坏。我认为这只是格式良好。 Ty –

0

另一种方法是使用Future interface。这样做会给你一些其他漂亮的功能。有些例子参见this

1

您还可以使用CountDownLatch指示线程是否完整。见https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html

像这样:

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(); 
} 

每个任务的线程将计算,当他们完成了一个钩向下。在// A创建的线程将一直等到锁存器计数到零。只有这样,才会打印“所有任务已完成”声明。所以基本上,doneSignal.await()之后的语句只会在所有线程完成后才执行。