我正在寻找一种设计模式,其中父线程将产生多个子线程。每个子线程将执行一些计算并返回适当的结果。
父线程将等待子线程完成。完成所有子线程后,合并的结果将被发送到父线程。
然后,父线程将继续使用合并结果。
答案 0 :(得分:0)
检查join
课程的Thread
方法。这是一个工作样本:
import java.lang.*;
public class Threads {
public void callChildren() throws Exception {
Thread t = new Thread(new ChildThread());
t.start();
t.join();
System.out.print(t.getName());
System.out.println(", status = " + t.isAlive());
}
public static void main(String[] args) throws Exception{
for(int i = 0 ; i < 4; i ++) {
new Threads().callChildren();
}
System.out.println("Printing from Parent thread after all child thread are complete.");
}
private class ChildThread implements Runnable{
@Override
public void run() {
System.out.println("Thread started:::"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread ended:::"+Thread.currentThread().getName());
}
}
}
答案 1 :(得分:0)
一些现有的答案建议手动生成线程 - 我不会这样做,而是使用ExecutorService
代替。
如果您被允许使用第三方库,Guava可以解决问题:将您的子任务提交到ListeningExecutorService
会给您一个ListenableFuture<T>
({{1}成为你的结果类型)。你可以,例如使用Futures.allAsList
将所有子任务未来合并到一个未来(封装结果值列表)。如果您等待这一个未来(使用get
),您将有效地等待所有子任务。完成后,您可以合并所有结果值并继续使用父逻辑。
这是一个非常小的例子:
T
如果您无法使用第三方库,则可以使用“传统”ExecutorService
生成子任务,并使用ExecutorCompletionService
处理生成的未来。链接的javadoc给出了问题的两个方面的例子。
答案 2 :(得分:-1)
线程无法返回结果。当创建者将对自身的引用(&#34; this&#34;)传递给创建的线程时,子线程可以与创建线程通信,例如:
MyThread thd1 = new MyThread(this, latch);
latch是对CountDownLatch的引用。创建者还有一个创建的线程在完成时将调用的方法,例如:
public void saveResult1 (Object something) {
object1 = something;
latch.countDown();
}
创建者只需等待所有线程完成等待。
try {
latch.await();
} catch (InterruptedException ignore) {}
当每个创建的线程完成其工作时,它可以在创建者线程上调用方法saveResult ...,将结果保存在某处并进行倒计时。