多线程编程是开发高并发应用的重点和难点,是许多互联网公司面试环节必不可少的部分.打算围绕多线程编程总结一些核心概念及它们之间的关系,本篇是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号苹果已装车
网友评论