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个已经到达,正在等候
**我最先执行*


相关文章
|
4月前
|
设计模式 Java
CountDownLatch和CyclicBarrier源码详解
我现在有个场景:现在我有50个任务,这50个任务在完成之后,才能执行下一个函数,要是你,你怎么设计?可以用JDK给我们提供的线程工具类,CountDownLatch和CyclicBarrier都可以完成这个需求。基于AQS实现,会将构造CountDownLatch的入参传递至statecountDown()就是在利用CAS将state减1,await)实际就是让头节点一直在等待state为0时,释放所有等待的线程。
41 1
|
6天前
|
Java
CountDownLatch用法、详解
CountDownLatch用法、详解
|
2天前
并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)
并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)
7 0
|
4月前
|
Java 调度
【多线程】Thread类的基本用法
【多线程】Thread类的基本用法
【多线程】Thread类的基本用法
|
5月前
CountDownLatch和CyclicBarrier的区别
CountDownLatch和CyclicBarrier的区别
21 0
|
8月前
CyclicBarrier 和 CountDownLatch 的实现原理与代码演示
CyclicBarrier 和 CountDownLatch 的实现原理与代码演示
99 0
|
8月前
|
程序员 调度
多线程之Thread 类的基本用法
多线程之Thread 类的基本用法
|
11月前
|
Java API C++
高并发编程-Thread#interrupt用法及源码分析
高并发编程-Thread#interrupt用法及源码分析
71 0
|
Java 程序员 Linux
Java多线程-线程的创建(Thread类的基本使用)
Java多线程-线程的创建(Thread类的基本使用)
115 0
Java多线程-线程的创建(Thread类的基本使用)

热门文章

最新文章