CyclicBarrier 字面意思是循环拦截器, 是java current包下的多线程协作的类, 创建此类必须出入一个 parties 值, 如果拦截的线程数达到 parties 值, 则会释放拦截的锁, 相关线程得以继续执行, 另外创建类对象时也可以在传入一个 Runnable 对象, 表示如果CyclicBarrier 达到释放锁的条件, 首先会开启 Runnable 线程 , 等此线程执行完毕后, 再释放拦截的锁
下面以选手比赛建立线程模型, 展示CyclicBarrier 类的使用:
package _CyclicBarrier;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cb = new CyclicBarrier(4,new Runnable() {
@Override
public void run() {
System.out.println("开始比赛");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
CyclicBarrier cb2 = new CyclicBarrier(4,new Runnable() {
@Override
public void run() {
System.out.println("比赛结束");
}
});
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 4; i++) {
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" 选手已经准备好 !!");
try {
cb.await();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+" 选手跑到了终点 !!");
try {
cb2.await();
} catch (Exception e) {
}
}
});
}
}
}
其执行的结果是:
pool-1-thread-2 选手已经准备好 !!
pool-1-thread-4 选手已经准备好 !!
pool-1-thread-3 选手已经准备好 !!
pool-1-thread-1 选手已经准备好 !!
开始比赛
pool-1-thread-1 选手跑到了终点 !!
pool-1-thread-2 选手跑到了终点 !!
pool-1-thread-4 选手跑到了终点 !!
pool-1-thread-3 选手跑到了终点 !!
比赛结束
注意执行的细节, 在输出开始比赛后会等待 1s
说到CyclicBarrier 就不得不与 CountDownLatch 进行比较, 实际上两者最大的区别就是 CyclicBarrier 可以复用,
同样以比赛构建线程模型 看一个改造后的例子 :
package _CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierDemo {
public static CyclicBarrier cb3 = new CyclicBarrier(2);
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
CyclicBarrier cb = new CyclicBarrier(4,new Runnable() {
@Override
public void run() {
System.out.println("开始比赛");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
CyclicBarrier cb2 = new CyclicBarrier(4,new Runnable() {
@Override
public void run() {
System.out.println("比赛结束");
try {
Thread.sleep(1000);
cb3.await();
} catch (Exception e) {
e.printStackTrace();
}
}
});
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 4; i++) {
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" 选手已经准备好 !!");
try {
cb.await();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+" 选手跑到了终点 !!");
try {
cb2.await();
} catch (Exception e) {
}
}
});
}
cb3.await();
System.out.println("==========准备下一次比赛==========");
Thread.sleep(2000);
for (int i = 0; i < 4; i++) {
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" 选手已经准备好 !!");
try {
cb.await();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+" 选手跑到了终点 !!");
try {
cb2.await();
} catch (Exception e) {
}
}
});
}
}
}
输出结果:
pool-1-thread-1 选手已经准备好 !!
pool-1-thread-3 选手已经准备好 !!
pool-1-thread-2 选手已经准备好 !!
pool-1-thread-4 选手已经准备好 !!
开始比赛
pool-1-thread-4 选手跑到了终点 !!
pool-1-thread-1 选手跑到了终点 !!
pool-1-thread-3 选手跑到了终点 !!
pool-1-thread-2 选手跑到了终点 !!
比赛结束
==========准备下一次比赛==========
pool-1-thread-1 选手已经准备好 !!
pool-1-thread-2 选手已经准备好 !!
pool-1-thread-3 选手已经准备好 !!
pool-1-thread-4 选手已经准备好 !!
开始比赛
pool-1-thread-4 选手跑到了终点 !!
pool-1-thread-1 选手跑到了终点 !!
pool-1-thread-2 选手跑到了终点 !!
pool-1-thread-3 选手跑到了终点 !!
比赛结束
使用 CyclicBarrier 可以轻松管理多线程任务;