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();
        }
    }
}

  

posted @ 2019-05-28 11:03  叮叮007  阅读(669)  评论(0编辑  收藏  举报