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 运行此代码时,它似乎总是陷入僵局。然而,当我在 1 级或 3 级使用 CyclicBarrier 运行代码时,即 new CyclicBarrier(1) 或 new CyclicBarrier(3),它总是成功完成。那么二级有什么问题呢?

4

1 回答 1

0

CyclicBarrier是循环的,这意味着它可以重复使用。当屏障被初始化时,被和argument 2绊倒后,新的一代开始。主线程不能单独跳闸。serviceOneThreadserviceTwoThread

也许你需要一个CountDownLatch.

于 2017-12-03T16:34:14.757 回答