CyclicBarrier的用法

简介:

 CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

  CyclicBarrier类似于CountDownLatch也是个计数器, 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被 唤醒前被执行。















构造方法摘要
**[CyclicBarrier](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#CyclicBarrier(int))**(int parties)
          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
**[CyclicBarrier](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#CyclicBarrier(int, java.lang.Runnable))**(int parties, [Runnable](http://www.cnblogs.com/java/lang/Runnable.html "java.lang 中的接口") barrierAction)
          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行

 





































方法摘要
int **[await](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#await())**()
          在所有参与者)都已经在此 barrier 上调用 await 方法之前,将一直等待。
int **[await](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#await(long, java.util.concurrent.TimeUnit))**(long timeout, [TimeUnit](http://www.cnblogs.com/java/util/concurrent/TimeUnit.html "java.util.concurrent 中的枚举") unit)
          在所有参与者)都已经在此屏障上调用 await 方法之前,将一直等待。
int **[getNumberWaiting](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#getNumberWaiting())**()
          返回当前在屏障处等待的参与者数目。
int **[getParties](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#getParties())**()
          返回要求启动此 barrier 的参与者数目。
boolean **[isBroken](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#isBroken())**()
          查询此屏障是否处于损坏状态。
void **[reset](http://www.cnblogs.com/java/util/concurrent/CyclicBarrier.html#reset())**()
          将屏障重置为其初始状态。

 

 1 package com.thread;
 2 import java.util.concurrent.CyclicBarrier;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6
 7 public class CyclicBarrierTest {
 8
 9     public static void main(String[] args) {
10         ExecutorService service = Executors.newCachedThreadPool();
11         final  CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
12         for(int i=0;i<3;i++){
13             Runnable runnable = new Runnable(){
14                     public void run(){
15                     try {
16                         Thread.sleep((long)(Math.random()10000));
17                         System.out.println(“线程” + Thread.currentThread().getName() +
18                                 “即将到达集合地点1,当前已有” + cb.getNumberWaiting() + “个已经到达,正在等候”);
19                         cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行
20
21                         Thread.sleep((long)(Math.random()10000));
22                         System.out.println(“线程” + Thread.currentThread().getName() +
23                                 “即将到达集合地点2,当前已有” + cb.getNumberWaiting() + “个已经到达,正在等候”);
24                         cb.await();
25                         Thread.sleep((long)(Math.random()*10000));
26                         System.out.println(“线程” + Thread.currentThread().getName() +
27                                 “即将到达集合地点3,当前已有” + cb.getNumberWaiting() + “个已经到达,正在等候”);
28                         cb.await();
29                     } catch (Exception e) {
30                         e.printStackTrace();
31                     }
32                 }
33             };
34             service.execute(runnable);
35         }
36         service.shutdown();
37     }
38 }


线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候

  如果在构造CyclicBarrier对象的时候传了一个Runnable对象进去,则每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable。如果把上面的例子改成下面这样:


 1 package com.thread;
 2 import java.util.concurrent.CyclicBarrier;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6
 7 public class CyclicBarrierTest {
 8
 9     public static void main(String[] args) {
10         ExecutorService service = Executors.newCachedThreadPool();
11         //final  CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
12         final  CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){
13             @Override
14             public void run() {
15                 System.out.println(“**我最先执行*“);
16             }
17         });
18         for(int i=0;i<3;i++){
19             Runnable runnable = new Runnable(){
20                     public void run(){
21                     try {
22                         Thread.sleep((long)(Math.random()10000));
23                         System.out.println(“线程” + Thread.currentThread().getName() +
24                                 “即将到达集合地点1,当前已有” + cb.getNumberWaiting() + “个已经到达,正在等候”);
25                         cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行
26
27                         Thread.sleep((long)(Math.random()10000));
28                         System.out.println(“线程” + Thread.currentThread().getName() +
29                                 “即将到达集合地点2,当前已有” + cb.getNumberWaiting() + “个已经到达,正在等候”);
30                         cb.await();    //这里CyclicBarrier对象又可以重用
31                         Thread.sleep((long)(Math.random()*10000));
32                         System.out.println(“线程” + Thread.currentThread().getName() +
33                                 “即将到达集合地点3,当前已有” + cb.getNumberWaiting() + “个已经到达,正在等候”);
34                         cb.await();
35                     } catch (Exception e) {
36                         e.printStackTrace();
37                     }
38                 }
39             };
40             service.execute(runnable);
41         }
42         service.shutdown();
43     }
44 }

则结果如下:

线程pool-1-thread-1即将到达集合地点1,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点1,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
**我最先执行*
线程pool-1-thread-1即将到达集合地点2,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已经到达,正在等候
**我最先执行*
线程pool-1-thread-1即将到达集合地点3,当前已有0个已经到达,正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有1个已经到达,正在等候
线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
**我最先执行*


相关文章
|
6月前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
66 0
|
5月前
|
Java 数据库 开发者
CountDownLatch、CyclicBarrier和Semaphore原理和区别
CountDownLatch、CyclicBarrier和Semaphore
|
5月前
CyclicBarrier原理
文章主要介绍了CyclicBarrier的工作原理和使用场景。CyclicBarrier适用于需要多个线程同步到达某个点后再一起继续执行的情况,它通过ReentrantLock和Condition实现了高效的线程同步机制,适合用于需要循环使用屏障点的场景。
CyclicBarrier原理
|
5月前
|
Java
CountDownLatch、CyclicBarrier 使用区别
CountDownLatch、CyclicBarrier 使用区别
40 1
|
8月前
|
Java API 调度
【Java多线程】Thread类的基本用法
【Java多线程】Thread类的基本用法
59 0
|
8月前
|
Java
CountDownLatch用法、详解
CountDownLatch用法、详解
|
8月前
|
并行计算 安全 Java
CyclicBarrier(循环屏障)源码解读与使用
CyclicBarrier(循环屏障)源码解读与使用
|
8月前
并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)
并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)
122 0
CountDownLatch和CyclicBarrier的区别
CountDownLatch和CyclicBarrier的区别
43 0
CyclicBarrier 和 CountDownLatch 的实现原理与代码演示
CyclicBarrier 和 CountDownLatch 的实现原理与代码演示
179 0