CyclicBarrier使用范例

网上查了几个例子,发现几乎都直接可以用CountDownLatch来替换,于是自己写了一个例子来说明CyclicBarrier的好处,jdk用的8。例子是用N个线程,每个线程分别同时开始填写第0列里面的N行数据,比如线程0填写0列0行并等待,线程1填写0列1行并等待。。。直到所有线程填写0列完成,再又开始同时填写第1列,直到填写完成。个人认为和CountDownLatch的最大区别在于,CyclicBarrier是可以重复使用的。

package concurrent;

import org.junit.Test;

import java.util.Random;
import java.util.concurrent.*;

/**
 * 栅栏
 *
 * @author Dean
 */
public class TestCyclicBarrier {
	private int N = 3; //线程数,也是行数
	private int columnNum = 4;//列数
	private int data[][] = new int[N][columnNum];
	private int currentColumn = 0; //当前处理列
	private CyclicBarrier cyclicBarrier;
	private boolean done = false;


	/**
	 * 模拟N个线程并发逐列填充二维数组并计算该列合计,例子模仿自CyclicBarrier JAVA API
	 */
	@Test
	public void test() throws InterruptedException {
		ExecutorService executorService = Executors.newCachedThreadPool();
		//CyclicBarrier也有无参构造函数
		cyclicBarrier = new CyclicBarrier(N, () -> {
			int total = data[0][currentColumn] + data[1][currentColumn] + data[2][currentColumn];
			System.out.println("第" + currentColumn + "列完成计算,合计=" + total);
			currentColumn++;
			//这里可以控制是否一直计算下去
			if (currentColumn == columnNum) {
				done = true;
			}
		});

		for (int i = 0; i < N; i++) {
			executorService.execute(new Worker(i));
		}

		while(!done){
			TimeUnit.SECONDS.sleep(2);//主线程等待
		}

		System.out.println("打印二维数组");
		for (int i = 0; i < N; i++) {
			System.out.print("[");
			for (int j = 0; j < columnNum; j++) {
				System.out.print(data[i][j] + "-");
			}
			System.out.println("]");
		}
	}

	private class Worker implements Runnable {
		int myRow;

		Worker(int row) {
			myRow = row;
		}

		@Override
		public void run() {
			while (!done) {
				try {
					TimeUnit.SECONDS.sleep(new Random().nextInt(5));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				int num = new Random().nextInt(9);
				System.out.println("当前列=" + currentColumn + ",当前行=" + myRow + ",数字=" + num);
				data[myRow][currentColumn] = num;
				try {
					cyclicBarrier.await();
				} catch (InterruptedException | BrokenBarrierException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

控制台输出:

当前列=0,当前行=1,数字=2
当前列=0,当前行=0,数字=2
当前列=0,当前行=2,数字=5
第0列完成计算,合计=9
当前列=1,当前行=1,数字=6
当前列=1,当前行=2,数字=3
当前列=1,当前行=0,数字=6
第1列完成计算,合计=15
当前列=2,当前行=0,数字=8
当前列=2,当前行=2,数字=0
当前列=2,当前行=1,数字=7
第2列完成计算,合计=15
当前列=3,当前行=0,数字=8
当前列=3,当前行=1,数字=6
当前列=3,当前行=2,数字=5
第3列完成计算,合计=19
打印二维数组
[2-6-8-8-]
[2-6-7-6-]
[5-3-0-5-]
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值