多线程06--CountDownLatch、CyclicBarrier、Semaphore

上一篇:多线程05--ReentrantLock 原理_fengxianaa的博客-CSDN博客

1. CountDownLatch

/**
 * CountDownLatch
 *      允许某个线程等待其他线程完成后再执行,工作中经常使用
 */
public class Lock04 {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(5);

        for(int i=0;i<5;i++){
            new Thread(() ->{
                try{
                    String name = Thread.currentThread().getName();
                    if("Thread-0".equals(name)){
                        System.out.println(name+"休息一下。。。");
                        Thread.sleep(3000);
                    }
                    System.out.println(name+"已经吃完饭。。。");
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    //  最好是将这句代码放在 finally 中,防止因为异常导致无法countDown
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println("都已经吃完饭。。。");
    }
}

2. CyclicBarrier

/**
 * CyclicBarrier
 *      循环屏障,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行
 *
 *      CyclicBarrier(int parties)
 *          parties:表示需要拦截的线程数
 *
 *      await()
 *          如果当前线程不是最后一个线程,那么调用此方法会被阻塞。除非以下某个场景出现:
 *              最后一个线程到达
 *              某个线程中断当前线程 或 另一个等待线程
 *              某个线程在等待 barrier 时超时
 *              某个线程在此 barrier 上调用 reset()
 *
 *          如果当前线程,在进入此方法时已经被中断 或 在等待时被中断,抛:InterruptedException
 *          如果线程在等待时被 中断,则其他等待线程都将抛出 BrokenBarrierException 异常,并将 barrier设为损坏状态
 */
public class Lock05 {

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

        Thread t0 = new Thread(() -> {
            try {
                String name = Thread.currentThread().getName();
                System.out.println(name + "到了。。。");
                cyclicBarrier.await();
                System.out.println(name + "开始吃饭。。。");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        t0.start();
        Thread.sleep(2000);


        Thread t1 = new Thread(() -> {
            try {
                String name = Thread.currentThread().getName();
                System.out.println(name + "到了。。。");
                cyclicBarrier.await();
                System.out.println(name + "开始吃饭。。。");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        t1.start();

//        Thread.sleep(1000);
//        t0.interrupt();
    }

3. Semaphore

/**
 * Semaphore
 *      信号量,控制同时访问特定资源的线程数量
 *
 *      Semaphore(int permits)
 *          接受一个整型的数字,表示可用的许可证数量
 *
 *      acquire()
 *          阻塞当前线程,直到获取一个许可证,阻塞时,如果被 interrupt,抛:InterruptedException
 *
 *      void release()
 *  *          释放一个许可,别忘了在finally中使用,注意:多次调用该方法,会使信号量的许可数增加,达到动态扩展的效果,如:初始permits为1, 调用了两次release,最大许可会改变为2
 *
 *      void acquire(int permits)
 *          获取指定数目的许可,如果无可用许可前也将会一直阻塞等待
 *
 *      boolean tryAcquire()
 *          从信号量尝试获取一个许可,如果无可用许可,直接返回false,不会阻塞
 *
 *      boolean tryAcquire(int permits)
 *          尝试获取指定数目的许可,如果无可用许可直接返回false
 *
 *      boolean tryAcquire(int permits, long timeout, TimeUnit unit)
 *          在指定的时间内尝试从信号量中获取许可,如果在指定的时间内获取成功,返回true,否则返回false
 *
 *      int availablePermits()
 *          获取当前信号量可用的许可
 */
public class Lock06 {
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        Semaphore semaphore = new Semaphore(2);

        for(int i=0;i<3;i++){
            new Thread(() -> {
                try {
                    semaphore.acquire();//获取许可证
                    String name = Thread.currentThread().getName();
                    System.out.println(name + "开始运行。。。");
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();//释放许可证
                }
            }).start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/fengxianaa/article/details/124427303