我想同时运行一些任务,所以我有一个看起来像这样的代码:
for(final Task task : tasks){
(new Thread(){public void run(){
task.run(args);
}}).start();
我怎么知道所有任务何时完成(任务量可能不同),以便我可以在完成所有任务后运行某些任务?
System.out.println("All tasks are finished");
答案 0 :(得分:5)
不是显式创建线程,而是将Runnables提交给ExecutorService,然后调用其shutdown和awaitTermination方法:
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);
答案 1 :(得分:5)
较短的版本是使用parallelStream
tasks.parallelStream().forEach(t -> t.run(args));
这将使用您拥有的所有CPU(如果您有足够的任务)运行所有任务,并等待全部完成。
答案 2 :(得分: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处创建的线程将等到锁存器已经倒计数到零。只有这样,&#34;所有任务完成&#34;声明将被打印。所以基本上,doneSignal.await()之后的语句只会在所有线程完成后执行。
答案 3 :(得分:1)
使用CyclicBarrier,例如: http://tutorials.jenkov.com/java-util-concurrent/cyclicbarrier.html
答案 4 :(得分: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 :(得分:0)
另一种方法是使用Future interface。这样做可以为您提供一些其他漂亮的功能。有关示例,请参阅this。