CountDownLatch和CyclicBarrier与Semaphore的区别

刚开始的时候我不能很好的理解门栓与循环等待的区别。书上讲的也不够清晰,说CyclicBarrier锁的是事务。
后来想了想觉得门栓就像一个准点出发的大巴车,它才不管有多少人await它只管时间到了才出发也就是count降到0。
而循环等待这个大巴车是看人数只要await的人数到了一定的界限就会发车。
使用的时候门栓的countdown+await=循环等待的await。这样看来门栓要比await更为灵活。
门栓示例

public class Test {
    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < 5; i++)
            new Thread(() -> {
                try {
                    latch.await();
                    System.out.println("观察阻塞情况");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        for (int i = 0; i < 5; i++)
            new Thread(() -> {
                synchronized (Test.class) {
                    latch.countDown();
                    System.out.println(latch.getCount());
                }
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
    }
}

运行结果
在这里插入图片描述
循环等待示例

public class Test {
    public static void main(String[] args) {
        CyclicBarrier cb = new CyclicBarrier(3);
        for (int i = 0; i < 2; i++)
            new Thread(() -> {
                try {
                    System.out.println("线程" + Thread.currentThread().getName() + "被阻塞");
                    cb.await();
                    System.out.println("阻塞解除");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, "" + i).start();
       //主线程中
        try {
            TimeUnit.SECONDS.sleep(3);
            System.out.println("线程"+Thread.currentThread().getName()+"被阻塞");
            cb.await();
            System.out.println("阻塞解除");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

运行结果
在这里插入图片描述
循环等待的构造函数中还可以加一个线程该线程在等待完成后优先执行,一般用于收尾工作代码如下:

        CyclicBarrier cb = new CyclicBarrier(3,()-> System.out.println("阻塞解除"));

信号量Semaphore类

public class Test {
    public static void main(String[] args) {
        Semaphore sema = new Semaphore(2,true);//可以设置是否公平
        for(int i = 0;i<10;i++)
            new Thread(()->{
                try {
                    sema.acquire();
                    System.out.println(Thread.currentThread().getName()+"请求信号量");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    sema.release();
                    System.out.println(Thread.currentThread().getName()+"释放信号量");
                }
            },"线程"+i).start();
    }
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值