1.CyclibcBarrier的线程运行到某个位置后即停止运行,直到所有的线程都到达这个点,所有线程才开始运行;CountDownLatch是线程运行到某个点后,计数器-1,程序继续运行
即CyclibcBarrier是run方法不运行,CountDownLatch是run方法不运行
2.CyclibcBarrier只能唤起一个任务,CountDownLatch可以唤起多个任务
3.CyclibcBarrier可重用,CountDownLatch不可重用,当计数为0就不可再用了
public class CyclicBarrierTest {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<String> sqls = new LinkedBlockingQueue<>();
// 每当有5线程处于await状态的时候,则会触发barrierAction执行
CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
// 这是每满足5次数据库操作,就触发一次批量执行
System.out.println("有5个线程执行了,开始批量插入: " + Thread.currentThread());
for (int i = 0; i < 5; i++) {
System.out.println(sqls.poll());
}
}
});
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
sqls.add("data - " + Thread.currentThread()); // 缓存起来
Thread.sleep(1000L); // 模拟数据库操作耗时
barrier.await(); // 等待栅栏打开,有5个线程都执行到这段代码的时候,才会继续往下执行
System.out.println(Thread.currentThread() + "插入完毕");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
Thread.sleep(2000);
}
}
import java.util.Random;
import java.util.concurrent.*;
/**
* CyclicBarrier
* 同步工具:允许一组线程共同等待一个壁垒点
* 适用于固定数量线程的同步
* 等待线程释放后可以重复使用
*
* Created by windwant on 2016/5/27.
*/
public class MyCyclicBarrier {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
CyclicBarrier cb = new CyclicBarrier(5, new MainTask());//MainTask可选
Random r = new Random();
es.execute(new SubTask(cb, r.nextInt(10), "task1"));
es.execute(new SubTask(cb, r.nextInt(10), "task2"));
es.execute(new SubTask(cb, r.nextInt(10), "task3"));
es.execute(new SubTask(cb, r.nextInt(10), "task4"));
es.execute(new SubTask(cb, r.nextInt(10), "task5"));
es.shutdown();
}
}
class MainTask implements Runnable {
public void run() {
try {
System.out.println("mian task begin");
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
System.out.println("============" + i + "============");
}
System.out.println("mian task implemented");
} catch (Exception e) {
e.printStackTrace();
}
}
}
class SubTask implements Runnable{
private CyclicBarrier cb;
private int seconds;
private String taskName;
SubTask(CyclicBarrier cb, int seconds, String taskName){
this.cb = cb;
this.seconds = seconds;
this.taskName = taskName;
}
public void run() {
try{
System.out.println("subtask " + taskName + " begin, need time: " + seconds + "s");
long b = System.currentTimeMillis();
for (int i = 0; i < seconds; i++) {
Thread.sleep(1000);
System.out.println("subtask: " + taskName + "============" + i + "============");
}
long d = System.currentTimeMillis() - b;
System.out.println("subtask " + taskName + " over, executing time: " + TimeUnit.SECONDS.convert(d, TimeUnit.MILLISECONDS));
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}