JUC---三个辅助类:CountDown/CyclicBarrier/Semaphore

1:CountDown(减少计数)

让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。

/**
 *
 * @Description:
 *  *让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。
 *
 * CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞。
 * 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),
 * 当计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行。
 *
 * 解释:6个同学陆续离开教室后值班同学才可以关门。
 *
 * main主线程必须要等前面6个线程完成全部工作后,自己才能开干
 * @author Lrc
 */
public class CountDownDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6 ; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"\t已离开");
                countDownLatch.countDown();
            }, CountryEnum.forEach_CountryEnum(i).getMessage()).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName()+"\t秦走了");
    }
}
齐	已离开
赵	已离开
燕	已离开
韩	已离开
楚	已离开
魏	已离开
main	秦走了

上面的例子可以看到,如果这六个同学都没有离开,主线程一致在堵塞,知道离开后开始执行下面的语句

使用方法:

  • 初始化设置计数器
  • 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),
  • 当计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行。

1:CyclicBarrier(循环栅栏)

  • CyclicBarrier
  • 的字面意思是可循环(Cyclic)使用的屏障(Barrier)。它要做的事情是,
  • 让一组线程到达一个屏障(也可以叫同步点)时被阻塞,
  • 直到最后一个线程到达屏障时,屏障才会开门,所有
  • 被屏障拦截的线程才会继续干活。
  • 线程进入屏障通过CyclicBarrier的await()方法。

在这里插入图片描述
构造器可以看到,需要传入一个Runnable

/**
*  让一组线程到达一个屏障(也可以叫同步点)时被阻塞,
 *   直到最后一个线程到达屏障时,屏障才会开门,所有
 *   被屏障拦截的线程才会继续干活。
 *      线程进入屏障通过CyclicBarrier的await()方法。
* 集齐七颗龙珠就可以召唤神龙
*
* @Author:LRC
* @Date:10:45 上午 2020/7/5
*/
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            //集齐七个之后需要做的时期
            System.out.println("已集齐,召唤神龙");
        });
        for (int i = 1; i <= 7; i++) {
            new Thread(()->{

                try {
                    System.out.println(Thread.currentThread().getName()+"\t收集到了");
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
1	收集到了
4	收集到了
3	收集到了
2	收集到了
6	收集到了
5	收集到了
7	收集到了
已集齐,召唤神龙

进程已结束,退出代码 0

这个辅助类就是,设置一个屏障,直到最后一个线程到达后,这个屏障才会开门

3:Semaphore(信号灯)

信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。
在信号量上我们定义两种操作:

  • acquire(获取) 当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减1),
  •   要么一直等下去,直到有线程释放信号量,或超时。
    
  • release(释放)实际上会将信号量的值加1,然后唤醒等待的线程。
public class SemaphoreDemo {
    public static void main(String[] args) {
        //三个停车位
        Semaphore semaphore = new Semaphore(3);

        //停六个停车位
        for (int i = 1; i <=6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"\t 号车进入停车位");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println(Thread.currentThread().getName()+"\t号车离开停车位");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    //释放资源
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

1	 号车进入停车位
3	 号车进入停车位
2	 号车进入停车位
2	号车离开停车位
3	号车离开停车位
1	号车离开停车位
4	 号车进入停车位
6	 号车进入停车位
5	 号车进入停车位
4	号车离开停车位
5	号车离开停车位
6	号车离开停车位
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值