2013-12-13 96 views
0

我想同時啓動兩個進程,並確保在繼續其他步驟之前完成它們。你能幫我嗎?我已經嘗試了線程,它不能同時啓動兩個並等待完成。如何同時啓動兩個進程然後等待兩個進程完成?

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

該OP沒有提及多少個處理器。雖然這在技術上可能是真實的,但對於應用程序來說,即使在單個處理器上,事情似乎也很容易發生。無論如何,它沒有解決這個問題。 – Gray

2

你的問題是你反覆等待三方,但只有兩個線程反覆調用await()。我希望你的代碼能夠立即打印:「再見,殘酷的世界!」兩次,然後「完成」,然後掛起,因爲循環正在等待第三個線程再次調用await(),但主線程現在已經終止。

一個解決方案是讓你的主線程循環,調用await()與你的任務相同的次數。但那樣會很醜陋。

我建議使用ExecutorServiceinvokeAll()方法。這將在(大約)同時將您的任務提交給服務,然後阻止,直到完成所有任務。如果您想嘗試提高任務開始的同時性,您可以添加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

相關問題