我想同时启动两个进程,并确保在继续执行其他步骤之前完成所有这些进程。你能帮我吗?我已经尝试过Thread,它不能同时启动两个并等到完成。
final CyclicBarrier gate = new CyclicBarrier(3);
Thread r2 = new Thread()
{
public void run()
{
try
{
int i = 0;
while (i < 3)
{
System.out.println("Goodbye, " + "cruel world!");
Thread.sleep(2000L);
i++;
gate.await();
}
}
catch (InterruptedException | BrokenBarrierException iex)
{
}
}
};
Thread r3 = new Thread()
{
public void run()
{
try
{
int i = 0;
while (i < 3)
{
System.out.println("Goodbye, " + "cruel world!");
Thread.sleep(2000L);
i++;
gate.await();
}
}
catch (InterruptedException | BrokenBarrierException iex)
{
}
}
};
r2.start();
r3.start();
gate.await();
System.out.println("Donew");
答案 0 :(得分:2)
您的问题是您反复等待三方,但只有两个线程反复呼叫await()
。我希望你的代码能够立即打印出来,“再见,残酷的世界!”两次,然后“完成”,然后挂起,因为循环正在等待第三个线程再次调用await()
,但主线程现在已经终止。
一个解决方案是让你的主线程循环,调用await()
与你的任务相同的次数。但那会很难看。
我建议使用invokeAll()
的{{1}}方法。这将在(大约)同时将您的任务提交给服务,然后阻止,直到所有任务完成。如果您想尝试改进任务开始的同时性,可以添加ExecutorService
,但看起来您更关心任务何时结束,而CyclicBarrier
将为此处理你。
invokeAll()
请注意我是如何通过随机等待时间来加油的。然而,final class Sample
implements Callable<Void>
{
private static final int ITERATIONS = 3;
private static final long AVG_TIME_MS = 2000;
public static void main(String[] args)
throws InterruptedException
{
List<Sample> tasks = Arrays.asList(new Sample(), new Sample());
ExecutorService workers = Executors.newFixedThreadPool(tasks.size());
for (int i = 1; i <= ITERATIONS; ++i) {
/* invokeAll() blocks until all tasks complete. */
List<Future<Void>> results = workers.invokeAll(tasks);
for (Future<?> result : results) {
try {
result.get();
}
catch (ExecutionException ex) {
ex.getCause().printStackTrace();
return;
}
}
System.out.printf("Completed iteration %d.%n", i);
}
workers.shutdown();
System.out.println("Done");
}
@Override
public Void call()
throws InterruptedException
{
/* The average wait time will be AVG_TIME_MS milliseconds. */
ThreadLocalRandom random = ThreadLocalRandom.current();
long wait = (long) (-AVG_TIME_MS * Math.log(1 - random.nextDouble()));
System.out.printf("Goodbye, cruel world! (Waiting %d ms)%n", wait);
Thread.sleep(wait);
return null;
}
}
等待,直到该迭代中的所有任务完成。
答案 1 :(得分:2)
您可以使用Thread.join()
等待子进程/线程完成。
您不应该需要CyclicBarrier
。
答案 2 :(得分:-3)