如何同时启动两个进程然后等待完成?

时间:2013-12-13 20:47:52

标签: java concurrency

我想同时启动两个进程,并确保在继续执行其他步骤之前完成所有这些进程。你能帮我吗?我已经尝试过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");

3 个答案:

答案 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)

  1. 单处理器机器是不可能的。
  2. 即使你在线程上找到很多答案,它也不会同时启动两个过程
  3. 如果您接受Relative Simultanity那将很容易。