2017-07-21 5 views
0

CyclicBarrierの次のコードに問題があります。サイクリック・バリアによるデッドロック?

MyJavaCyclicBarrierExample.java::::::: 

      import java.util.Date; 
      import java.util.concurrent.BrokenBarrierException; 
      import java.util.concurrent.CyclicBarrier; 

      public class MyJavaCyclicBarrierExample { 

       public static void main(String[] args) { 

        //3 threads are part of the barrier, ServiceOne, ServiceTwo and this main thread calling them. 

        final CyclicBarrier barrier = new CyclicBarrier(2); 
        Thread serviceOneThread = new Thread(new ServiceOne(barrier)); 
        Thread serviceTwoThread = new Thread(new ServiceTwo(barrier)); 

        System.out.println("Starting both the services at "+new Date()); 

        serviceOneThread.start(); 
        serviceTwoThread.start(); 

        //Lets say main also has to do some work 
        try { 
         System.out.println("Main is going to do some work...."); 
         Thread.sleep(10000); 
         System.out.println("Main has finished its work...."); 
       } catch (InterruptedException e1) { 
        e1.printStackTrace(); 
       } 

        try { 
         System.out.println("Main is now going to wait at the barrier...."); 
         barrier.await(); 
         System.out.println("Main woken up at the barrier...."); 
        } catch (InterruptedException e) { 
         System.out.println("Main Thread interrupted!"); 
         e.printStackTrace(); 
        } catch (BrokenBarrierException e) { 
         System.out.println("Main Thread interrupted!"); 
         e.printStackTrace(); 
        } 
        System.out.println("Ending both the services at "+new Date()); 
       } 
      } 


     ServiceOne.java ::::::::: 
     import java.util.concurrent.BrokenBarrierException; 
     import java.util.concurrent.CyclicBarrier; 

     public class ServiceOne implements Runnable { 
      private final CyclicBarrier cyclicBarrier; 

      public ServiceOne(CyclicBarrier cyclicBarrier) { 
       this.cyclicBarrier = cyclicBarrier; 
      } 

      @Override 
      public void run() { 
       System.out.println("Starting service One..."); 
       try { 
        Thread.sleep(3000); //assuming service one does some business logic here... 
       } catch (InterruptedException e1) { 
        e1.printStackTrace(); 
       } 
       System.out.println("Service One has finished its work... waiting for others..."); 
       try { 
         System.out.println("ServiceOne is now going to wait at the barrier...."); 
         cyclicBarrier.await();  //Let's wait for the other threads at the cyclic barrier. 
         System.out.println("ServiceOne woken up at the barrier...."); 
       } catch (InterruptedException e) { 
        System.out.println("Service one interrupted!"); 
        e.printStackTrace(); 
       } catch (BrokenBarrierException e) { 
        System.out.println("Service one interrupted!"); 
        e.printStackTrace(); 
       } 
       System.out.println("The wait is over, lets complete Service Two!"); 
      } 
     } 



ServiceTwo.java::::::::: 

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CyclicBarrier; 
public class ServiceTwo implements Runnable { 
    private final CyclicBarrier cyclicBarrier; 
    public ServiceTwo(CyclicBarrier cyclicBarrier) { 
     this.cyclicBarrier = cyclicBarrier; 
    } 
    @Override 
    public void run() { 
     System.out.println("Starting service Two...."); 
     try { 
      Thread.sleep(2000);    //assuming service one does some business logic here... 
     } catch (InterruptedException e1) { 
      e1.printStackTrace(); 
     } 
     System.out.println("Service Two has finished its work.. waiting for others..."); 
     try { 
      System.out.println("ServiceTwo is now going to wait at the barrier...."); 
      cyclicBarrier.await();     //Let's wait for the other threads at the cyclic barrier. 
      System.out.println("ServiceTwo woken up at the barrier...."); 
     } catch (InterruptedException e) { 
      System.out.println("Service one interrupted!"); 
      e.printStackTrace(); 
     } catch (BrokenBarrierException e) { 
      System.out.println("Service one interrupted!"); 
      e.printStackTrace(); 
     } 
     System.out.println("The wait is over, lets complete Service One!"); 
    } 
} 

私はCyclicBarrierで2つのレベルでこのコードを実行すると、常にデッドロックに終わってしまいます。一方、レベル1または3、つまり新しいCyclicBarrier(1)または新しいCyclicBarrier(3)でCyclicBarrierでコードを実行すると、常に正常に完了します。レベル2の問題は何ですか?

+0

最小限の例を示してください。あなたのコードは無関係な情報でいっぱいです – GalAbra

答えて

0

CyclicBarrierは、再利用可能であることを意味します。障壁がargument 2で初期化され、serviceOneThreadserviceTwoThreadによってトリップされた後、新しい世代が始まります。メインスレッドは単独ではトリップできません。

おそらくCountDownLatchが必要です。

関連する問題