栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。
package com.example.demo.util.dxc;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.FutureTask;
/**
* 测试CyclicBarrier 循环栅栏
*/
public class TestCycliBarrier {
public void test() throws Exception {
int threadNum = 10;
Integer total = 0;
CyclicBarrier cyclicBarrier1 = new CyclicBarrier(threadNum, new Runnable() {
//最后一个线程到栅栏后要做的任务
@Override
public void run() {
System.out.println("准备就绪,开始计算...");
}
});
List<FutureTask<Integer>> list = new ArrayList<>();
for (int j = 0; j < threadNum; j++) {
FutureTask<Integer> future = new FutureTask<Integer>(new MyCallThread(cyclicBarrier1));
Thread thread = new Thread(future);
thread.start();
list.add(future);
}
for (FutureTask<Integer> integerFutureTask : list) {
total += integerFutureTask.get();
}
System.out.println("计算结果:" + total);
}
public static void main(String[] args) throws Exception {
new TestCycliBarrier().test();
}
}
package com.example.demo.util.dxc;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
public class MyCallThread implements Callable<Integer> {
private CyclicBarrier cyclicBarrier;
public MyCallThread(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public Integer call() throws Exception {
int num = 0;
for (int i = 0; i <= 100; i++) {
num += i;
}
System.out.println(Thread.currentThread().getName() + ":befor");
//等待所有线程到达之后才会返回num
cyclicBarrier.await();
System.out.println(Thread.currentThread().getName() + ":after");
return num;
}
}