CyclibcBarrier与CountDownLatch区别
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(); } } }