Java并发程序设计(19)并发锁之循环障碍CyclicBarrier

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发程序设计(19)并发锁之循环障碍CyclicBarrier相关的知识,希望对你有一定的参考价值。

1.1. 循环障碍CyclicBarrier

 

CyclicBarrier用于多个线程在某个同步点达到同步。在所有线程都到达该同步点之前,已经到达同步点的线程会等待其他线程。简单理解可以说CyclicBarrier跟一个旅游团出去旅游是类似的。在旅游团所有队员都到达出发集合地点之前,提前达到的队员只能在集合地点等待其他队员。当所有队员都达到后就可以出发了。循环障碍可以类似于旅游团在每个集合地点都这么等待一次,然后统一前往下一个景点。

 

package com.test.concurrence;

 

import java.util.Date;

import java.util.Random;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

 

public class CyclicBarrierTest {

 

public static void main(String[] args) {

//总共10个parties:这里是10个线程。

final CyclicBarrier  cyclicBarrier = new CyclicBarrier(10);

ExecutorService  executorService = Executors.newFixedThreadPool(10);

for(int i=0;i<10;i++){

executorService.submit(new Runnable(){

 

@Override

public void run() {

try {

                       //随机暂停一段时间,模拟提前达到。

Thread.sleep(1000* new Random().nextInt(20));

System.out.println("waiting:" + cyclicBarrier.getNumberWaiting()

 + " , parties:" + cyclicBarrier.getParties()

 + " , " + new Date());

                      //提前达到的线程等待还没到达的线程。

cyclicBarrier.await();

} catch (InterruptedException | BrokenBarrierException e) {

e.printStackTrace();

}

//所有线程都到了。

System.out.println("ready:" + cyclicBarrier.getNumberWaiting()

 + " , parties:" + cyclicBarrier.getParties()

 + " , " + new Date());

 

}

 

});

}

 

executorService.shutdown();

 

 

}

 

}

 

 

 

运行结果如下:

waiting:0 , parties:10 , Sat Mar 18 22:40:06 CST 2017

waiting:0 , parties:10 , Sat Mar 18 22:40:06 CST 2017

waiting:0 , parties:10 , Sat Mar 18 22:40:06 CST 2017

waiting:3 , parties:10 , Sat Mar 18 22:40:10 CST 2017

waiting:4 , parties:10 , Sat Mar 18 22:40:13 CST 2017

waiting:5 , parties:10 , Sat Mar 18 22:40:19 CST 2017

waiting:5 , parties:10 , Sat Mar 18 22:40:19 CST 2017

waiting:7 , parties:10 , Sat Mar 18 22:40:22 CST 2017

waiting:8 , parties:10 , Sat Mar 18 22:40:23 CST 2017

waiting:8 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

ready:0 , parties:10 , Sat Mar 18 22:40:23 CST 2017

 

 

CyclicBarrier的构造函数可以接收一个Runnable对象,当所有线程达到后就会执行此对象的run方法。

package com.test.concurrence;

 

import java.util.Date;

import java.util.Random;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

 

public class CyclicBarrierTest2 {

 

public static void main(String[] args) {

 

final CyclicBarrier  cyclicBarrier = new CyclicBarrier(10 , new Runnable(){

 

@Override

public void run() {

System.out.println("ready " + new Date());

 

}

 

});

ExecutorService  executorService = Executors.newFixedThreadPool(10);

for(int i=0;i<10;i++){

executorService.submit(new Runnable(){

 

@Override

public void run() {

try {

Thread.sleep(1000* new Random().nextInt(20));

System.out.println("waiting:" + cyclicBarrier.getNumberWaiting()

 + " , parties:" + cyclicBarrier.getParties()

 + " , " + new Date());

cyclicBarrier.await();

} catch (InterruptedException | BrokenBarrierException e) {

e.printStackTrace();

}

 

 

}

 

});

}

 

executorService.shutdown();

 

 

}

 

}

 

 

waiting:0 , parties:10 , Sat Mar 18 22:59:54 CST 2017

waiting:1 , parties:10 , Sat Mar 18 22:59:58 CST 2017

waiting:2 , parties:10 , Sat Mar 18 22:59:59 CST 2017

waiting:3 , parties:10 , Sat Mar 18 23:00:01 CST 2017

waiting:4 , parties:10 , Sat Mar 18 23:00:02 CST 2017

waiting:5 , parties:10 , Sat Mar 18 23:00:03 CST 2017

waiting:6 , parties:10 , Sat Mar 18 23:00:06 CST 2017

waiting:7 , parties:10 , Sat Mar 18 23:00:07 CST 2017

waiting:8 , parties:10 , Sat Mar 18 23:00:08 CST 2017

waiting:9 , parties:10 , Sat Mar 18 23:00:11 CST 2017

ready Sat Mar 18 23:00:11 CST 2017

 

以上是关于Java并发程序设计(19)并发锁之循环障碍CyclicBarrier的主要内容,如果未能解决你的问题,请参考以下文章

Java并发程序设计(21)并发锁之交换器Exchanger

Java并发程序设计(16)并发锁之条件变量

Java并发程序设计(20)并发锁之倒数锁CountDownLatch

Java并发程序设计(12)并发锁之可重入锁ReentrantLock

Java并发程序设计(15)并发锁之读写锁(续二)写锁降级

Java 并发:倒计时锁存器与循环障碍