2013-12-13 3 views
0

Я хочу начать два процесса одновременно и завершить их все, прежде чем приступать к другим шагам. Вы можете помочь? Я уже пробовал 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

Просьба показать, какие исследования вы сделали и что вы пробовали. Благодарю. – Gray

+1

Вы говорите, что уже пытались использовать 'Thread'. Можете ли вы показать нам код, с которым вы экспериментировали? Это позволит более четко понять, что вы пробовали, и (если вы объясните), чего вы хотите достичь. –

ответ

-3
  1. Это невозможно для однопроцессорных машин.
  2. Даже если вы найдете много ответов на темы, это не приведет к запуску двух процессов одновременно.
  3. Если вы принимаете Relative Simultanity, это будет легко.
+0

ОП не упоминает о том, сколько процессоров. И хотя это может быть технически справедливо, для приложения легко добиться того, что все происходит одновременно, даже на одном процессоре. Независимо от того, это не затрагивает вопрос. – Gray

2

Ваша проблема в том, что вы неоднократно ожидали трех сторон, но только два потока вызывают await() несколько раз. Я бы ожидал, что ваш код немедленно напечатает: «До свидания, жестокий мир!» дважды, и «Готово», а затем зависание, потому что петли ждут, когда третий поток снова вызовет await(), но основной поток уже завершен.

Одно решение для вашего основного потока для цикла, вызывая await() столько же раз, сколько и делает ваша задача. Но это было бы отвратительно.

Я бы предложил использовать метод invokeAll() для 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; 
    } 

} 

Обратите внимание на то, как я подправил вещи случайным временем ожидания. Тем не менее, invokeAll() ждет, пока все задачи в этой итерации не закончатся.

+0

'Thread.join()' это путь. В этом случае CyclicBarrier немного слишком тяжелый для моего вкуса. – Floegipoky

+0

Мы действительно не знаем, что это такое. 'CyclicBarrier' может быть полезен, если задачи выполняются повторно. Создание новых потоков только для удобства их метода join() может быть расточительным. – erickson

2

Вы можете использовать Thread.join(), чтобы дождаться завершения ваших подпроцессов/потоков. Вам не нужен CyclicBarrier.

Смежные вопросы