CyclicBarrier与CountDownLatch

CyclicBarrier

相当于栅栏拦截

我们通过构造方法

public CyclicBarrier(int parties) //parties指明需要拦截的线程的数目
public CyclicBarrier(int parties,Runnable barrierAction) //barrierAction表明所有线程拦截后要做的任务(由最后一个线程做)

我们通过

public int await() throws ...

调用await()方法表示把当前线程拦截,同时计数器会自动 -- ,一旦减到0表明所有的线程都被拦截此时会完成最后的任务,释放所有的线程,计数器重新恢复到parties(这是可以复用的关键

例:

static class test implements Runnable {
        CyclicBarrier cyclicBarrier;

        public test(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName()+"被拦截");
                cyclicBarrier.await();
                System.out.println(Thread.currentThread().getName()+"被释放");

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
    public static void main(String[] args) {
       CyclicBarrier cyclicBarrier=new CyclicBarrier(5, new Runnable() {
           @Override
           public void run() {
               System.out.println(Thread.currentThread().getName()+"完成最后的任务");
                       
           }
       });
       for(int i=0;i<5;i++){
           new Thread(new test(cyclicBarrier)).start();
       }

    }

CountDownLatch

构造器

public CountDownLatch(int count) //count为要等待多少个线程执行完

我们通过

public void await() throws InterruptedException{}

将某个线程阻塞

如果一个线程执行完成我们需要显式调用

public void countDown(){}

count--,直到count减为0说明所有线程都已经执行完毕,释放被阻塞的线程

不能复用

例:

static class test implements Runnable {
        CountDownLatch countDownLatch;

        public test(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(3000);
                System.out.println(Thread.currentThread().getName()+"执行完成");


            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                countDownLatch.countDown();
            }

        }
    }
    public static void main(String[] args) {
       System.out.println(Thread.currentThread().getName()+"被阻塞等待其他线程");
       CountDownLatch countDownLatch=new CountDownLatch(5);
       for(int i=0;i<5;i++){
           new Thread(new test(countDownLatch)).start();
       }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"完成");
    }

CyclicBarrier与CountDownLatch比较

1.CountDownLatch计数器叫state 是利用CAS 确保线程安全,CyclicBarrier的计数器叫count是通过ReentranLock保证线程安全

2.我们通常使用CountDownLatch阻塞主线程,CyclicBarrier阻塞任务线程

3.CountDownLatch是一次性的,CyclicBarrier可以复用

posted @ 2021-03-30 20:34  刚刚好。  阅读(62)  评论(0编辑  收藏  举报