多线程的工具类介绍

这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

工具类

CountDownLatch

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

 // 减法计数器   ,new 对象的时候指定总数 5
        CountDownLatch countDownLatch = new CountDownLatch(5);
​
        for (int i = 0; i < 5; i++) {
​
            new Thread(()->{
                // 每当执行完一次任务,将其数量-1
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName()+":"+countDownLatch.getCount());
            },String.valueOf(i)).start();
        }
        // 当数量变为0时,await()就会被唤醒,后面的代码继续执行,如果没有变成0,就不会执行
        countDownLatch.await();
        System.out.println("111");
​
复制代码

image.png

这里发现但count没有变为0,循环结束了,到await的时候没有被唤醒,就无法输出111

CyclicBarrier

加法计数器。当增加的数量达到指定的数量,就会执行里面的方法

// cyclicBarrier 的方法
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5,()->{
            System.out.println("当cyclicBarrier达到5个,就会执行输出该语句(执行操作)");
        });
​
        for (int i = 0; i < 4; i++) {
            new Thread(()->{
                try {
                    // 给数量+1
                    cyclicBarrier.await();
                    System.out.println(Thread.currentThread().getName()+":"+cyclicBarrier.getNumberWaiting());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
复制代码

CountDownLathc和CyclicBarrier的区别

1.CountDownLathc是一次性的,当达到条件执行完后就会停止

2.CyclicBarrier是可复用的

semaphore

相当于许可证,只有拿到许可证的人才能执行操作。操作完之后释放许可证给其他人。

// new时定义了该实例拥有几个sunc锁
public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }
​
// 拿到1个锁
public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
复制代码
// 限定3个锁
        Semaphore semaphore = new Semaphore(3);
​
        for (int i = 1; i <=6 ; i++) {
            new Thread(()->{
                try {
                    // 这个线程得到1个锁,许可证数量-1 ,如果许可证数量为0,等待其他线程释放锁.
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"获得锁");
​
                    // 等待2秒后释放
                    TimeUnit.SECONDS.sleep(2);
​
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    // 释放锁,使许可证+1
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName()+"释放锁");
                }
            }, String.valueOf(i)).start();
        }
​
复制代码

image.png

并发限流,限制最大并发数

猜你喜欢

转载自juejin.im/post/7036163242296606756
今日推荐