美文网首页
CyclicBarrier使用案例

CyclicBarrier使用案例

作者: nextliving | 来源:发表于2018-04-22 12:52 被阅读13次

多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念及它们之间的关系,本篇是CyclicBarrier.

CyclicBarrier

简介

CyclicBarrier是JDk1.5中引入的,属于线程同步辅助工具

使用场景

CyclicBarrier可以类比于一个栅栏,线程执行的时候会不断靠近这个栅栏,直到被堵在栅栏门口,然后等待其它所有的线程也到达栅栏门口.CyclicBarrier初始化时需要指定线程数,表示要这些线程都执行到指定的栅栏门口时打开闸门,然后每个线程继续执行.每个线程持有同一个CyclicBarrier,到达栅栏门口时会调用CyclicBarrier的await()方法,该方法会使CyclicBarrier的计数减1,该计数的初始值是CyclicBarrier初始化时指定的线程数.当所有的线程都到达栅栏门口时,计数减为0,门会打开.

循环使用

CyclicBarrier中的cyclic意思是循环,也就是每次计数建为0以后会自动恢复成初始化时的计数,并不需要调用CyclicBarrier的reset()方法让它恢复初始状态.参考When to reset CyclicBarrier in java multithreading.

案例

案例简介

现在需要从树上摘苹果,摘够指定的数量以后将苹果装车.注意: 一个线程摘一个苹果.

案例代码

主要分为2个类,Apple.java和AppleTest.java.

Apple.java

代码如下:


package com.ms.thread.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

/**

 * @author chenxin

 * @since 2018-04-19

 */

public class Apple implements Runnable {

//所有的apple持有同一个CyclicBarrier实例

private CyclicBarrier cb;

//CyclicBarrier中指定的摘苹果的线程数.一个线程生命周期内只能摘一个苹果

private int num;

public Apple(CyclicBarrier cb,int num) {

this.cb = cb;

this.num = num;

}

@Override

public void run() {

System.out.println(num+"号苹果已经摘下来了");

try {

cb.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

System.out.println(num+"号苹果已装车");

}

}

AppleTest.java

代码如下:


package com.ms.thread.cyclicbarrier;

import java.util.concurrent.CyclicBarrier;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import org.junit.Test;

/**

 * @author chenxin

 * @since 2018-04-19

 */

public class AppleTest {

//摘苹果的线程数

private static int appleCount = 10;

@Test

public static void main(String[] args) {

ExecutorService service = Executors.newFixedThreadPool(appleCount);

CyclicBarrier cb = new CyclicBarrier(appleCount, new Runnable() {

//当摘够指定数量(appleCount)的苹果以后执行该方法

@Override

public void run() {

System.out.println("***苹果数量够了,开始装车...***");

}

});

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

Apple apple = new Apple(cb, i);

service.execute(apple);

}

}

}

执行结果

结果如下:


0号苹果已经摘下来了

3号苹果已经摘下来了

2号苹果已经摘下来了

1号苹果已经摘下来了

5号苹果已经摘下来了

4号苹果已经摘下来了

6号苹果已经摘下来了

7号苹果已经摘下来了

8号苹果已经摘下来了

9号苹果已经摘下来了

***苹果数量够了,开始装车...***

9号苹果已装车

0号苹果已装车

3号苹果已装车

1号苹果已装车

4号苹果已装车

8号苹果已装车

2号苹果已装车

7号苹果已装车

5号苹果已装车

6号苹果已装车

参考

相关文章

网友评论

      本文标题:CyclicBarrier使用案例

      本文链接:https://www.haomeiwen.com/subject/lzaqlftx.html