美文网首页
3、concurrent包下常用的辅助类

3、concurrent包下常用的辅助类

作者: i小雨 | 来源:发表于2020-11-17 18:09 被阅读0次

    CountDownLatch:(减法计数器)

    1605603006(1).jpg

    示例:

    package com.company.add;
    
    import java.util.concurrent.CountDownLatch;
    
    //减法计数器功能
    //以教室6个学生出门为例,只有6个学生都出门了才能锁门
    public class TestCountDownLatch {
    
        public static void main(String[] args) throws InterruptedException {
            //总数为6
            CountDownLatch countDownLatch = new CountDownLatch(6);
    
            for (int i = 1; i <= 6; i++) {
                new Thread(()->{
                    System.out.println(Thread.currentThread().getName()+"出门了");
                    countDownLatch.countDown();  //数量-1
                },String.valueOf(i)).start();
            }
    
            countDownLatch.await();  //等待计数器归零,然后才会继续执行下面的程序。
            System.out.println("管理员关门了");
    
        }
    
    }
    
    

    结果:

    1出门了
    3出门了
    2出门了
    4出门了
    5出门了
    6出门了
    管理员关门了
    

    分析:
    countDownLatch.countDown(); //数量-1
    countDownLatch.await(); //等待计数器归零,然后才会继续执行下面的程序。
    线程每次调用countdown(),计数器数量减1,
    假设计数器数量减为了0,countDownLatch.await();就会被唤醒,继续执行。

    CyclicBarrier:(加法计数器)

    package com.company.add;
    
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    //加法计数器功能
    //以集齐七龙珠后变神龙为例
    public class TestCyclicBarrier {
    
        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
                System.out.println("变神龙");
            });
    
            for (int i = 1; i <= 7; i++) {
                final int temp = i; //内部类调用不到外部类的变量
                new Thread(()->{
                    System.out.println(Thread.currentThread().getName()+"收集了第"+temp+"龙珠");
                    try {
                        cyclicBarrier.await();  //等待计数器变成7
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        }
    }
    
    

    结果:

    Thread-1收集了第2龙珠
    Thread-0收集了第1龙珠
    Thread-2收集了第3龙珠
    Thread-3收集了第4龙珠
    Thread-5收集了第6龙珠
    Thread-4收集了第5龙珠
    Thread-6收集了第7龙珠
    变神龙
    

    Semaphore:(信号量)

    package com.company.add;
    
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.TimeUnit;
    
    //模拟停车位为三个,有6辆车。
    public class TestSemaphore {
    
        public static void main(String[] args) {
            //线程数量:停车位3个  (可应用于限流)
            Semaphore semaphore = new Semaphore(3);
    
            for (int i = 1; i <= 6; i++) {
                new Thread(()->{
                    try {
                        semaphore.acquire();//acquire()得到一个车位
                        System.out.println(Thread.currentThread().getName()+"抢到车位");
                        TimeUnit.SECONDS.sleep(3); //占用3秒钟
                        System.out.println(Thread.currentThread().getName()+"离开车位");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        semaphore.release(); //释放车位
                    }
                },String.valueOf(i)).start();
            }
    
    
        }
    }
    

    结果:

    1抢到车位
    2抢到车位
    3抢到车位
    3离开车位
    2离开车位
    4抢到车位
    1离开车位
    5抢到车位
    6抢到车位
    6离开车位
    4离开车位
    5离开车位
    

    分析:
    semaphore.acquire(); //获得,假设已经满了,会一直等待知道有被释放的为止
    semaphore.release(); //释放,会将当前的信号量+1,然后唤醒等待线程!
    作用:多个资源互斥使用!并发限流,控制最大的线程数

    相关文章

      网友评论

          本文标题:3、concurrent包下常用的辅助类

          本文链接:https://www.haomeiwen.com/subject/zdzxiktx.html