一分钟系列: 闭锁与栅栏

闭锁与栅栏

在介绍闭锁和栅栏之前,我们先来看下这个实例:

我们用三个线程实现男女朋友去看电影的示例,正常情况是需要男女双方都到达后才能一起去看电影,我们看下这段代码:

public class DownLatch {

    private static CountDownLatch countDownLatch = new CountDownLatch(2);
    public static void main(String[] args) throws  InterruptedException {
        new Thread(() -> {
                downLatch.girlArriveMovie();
            }).start();
        new  Thread(()-> {
                downLatch.boyArriveMovie();
        }).start();    
        downLatch.startWatchMovie();
    }
    public  void girlArriveMovie(){
        System.out.println("女孩到达电影院");
    }
    public void boyArriveMovie(){
        System.out.println("男生到达电影院");
    }
    public void startWatchMovie(){
        System.out.println("男女生都到达电影院,开始看电影");
    }
}

可能结果之一:

女孩到达电影院
男女生都到达电影院,开始看电影
男生到达电影院

可能结果之二:

女孩到达电影院
男生到达电影院
男女生都到达电影院,开始看电影

这和我们理想的情况不一样,来看看如何使用闭锁以及栅栏达到我们想要的理想结果。

闭锁

闭锁是一种同步工具。类似于一扇门:在使用闭锁的所有线程到达结束状态之前,这扇门一直是关闭着的。不允许任何线程通过,当到达结束状态时这扇门就会打开并允许所有闭锁相关的线程通过,且当打开了,就永远保持打开状态。
作用:可以用来确保某些任务等到其他任务完成之后才开始执行。

   public class DownLatch {

    private static CountDownLatch countDownLatch = new CountDownLatch(2);

    public static void main(String[] args) throws  InterruptedException {

        DownLatch downLatch = new DownLatch();

        new Thread(() -> {
                downLatch.girlArriveMovie();
                countDownLatch.countDown();
            }).start();
        new  Thread(()-> {
                downLatch.boyArriveMovie();
                countDownLatch.countDown();
        }).start();
        countDownLatch.await();
        downLatch.startWatchMovie();
    }

    public  void girlArriveMovie(){
        System.out.println("女孩到达电影院");
    }

    public void boyArriveMovie(){
        System.out.println("男生到达电影院");
    }

    public void startWatchMovie(){
        System.out.println("男女生都到达电影院,开始看电影");
    }

} 

女孩到达电影院
男生到达电影院
男女生都到达电影院,开始看电影

来看下如何使用闭锁达到我们想要的效果的。

new CountDownLatch(2);
//设置计数器为2
 countDownLatch.countDown();
 // 计数器减一
countDownLatch.await();
//是否计数器未0,如果是等待其他线程执行完毕
//后在执行main线程里的downLatch.startWatchMovie();
//方法

栅栏

栅栏和闭锁可以达到相同的效果,但是不同的是栅栏是等待所有的栅栏工作线程中都到达某一步,所有的栅栏工作线程才会继续执行。


public class CyclicBarrierExample {


    public final static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);


    public static void main(String[] args) {

        CyclicBarrierExample cyclicBarrierExample = new CyclicBarrierExample();
        ExecutorService threadPool = Executors.newFixedThreadPool(2);

        threadPool.execute(() -> cyclicBarrierExample.girlArriveMovie());
        threadPool.execute(() -> cyclicBarrierExample.boyArriveMovie());

        threadPool.shutdown();
    }


    public  void girlArriveMovie(){
        System.out.println("女孩到达电影院");
        try {
            Thread.sleep(500);
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        startWatchMovie();

    }

    public void boyArriveMovie(){
        System.out.println("男生到达电影院");
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        startWatchMovie();
    }

    public void startWatchMovie(){
        System.out.println("男女生都到达电影院,开始看电影");
    }
}

输出结果:

女孩到达电影院
男生到达电影院
男女生都到达电影院,开始看电影
男女生都到达电影院,开始看电影
Thread.sleep(500);
// 执行到这里睡眠500ms
 cyclicBarrier.await();
 //等待其他的栅栏工作线程
 //执行到这里
 //才会继续往下执行
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值