首页 > 技术文章 > 并发编程-JUC的三个常用工具类

seizedays 2020-03-25 10:34 原文

1、CountDownLatch:减法计数器

代码实例

public class CountDownLatchTest {
    public static void main(String[] args) {
        //优先执行,执行完毕之后,才能执行 main
        //1、实例化计数器,100
        CountDownLatch countDownLatch = new CountDownLatch(100);
        new Thread(()->{
            for (int i = 0; i < 100; i++) {
                System.out.println("++++++++++Thread");
                countDownLatch.countDown();
            }
        }).start();
​
​
        //2、调用 await 方法 让主线程等待countdonwn运行完毕
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
​
        for (int i = 0; i < 100; i++) {
            System.out.println("main--------------");
        }
    }
}

countDown() 计数器减一

await() 计数器停止,唤醒其他线程

new CountDownLatch(100)、coutDown()、await() 必须配合起来使用,创建对象时赋的值是多少,coutDown() 就要执行多少次,否则计数器不会清零,计数器就不会停止后,其他线程无法唤醒。

2、CyclicBarrier:加法计数器

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
​
public class CyclicBarrierTest {
    public static void main(String[] args) {
        //定义一个计数器,当计数器的值累加到10,输出"放行"
        CyclicBarrier cyclicBarrier = new CyclicBarrier(30,()->{
            System.out.println("放行");
        });
​
        for (int i = 1; i <= 90; i++) {
            final int temp = i;
​
            new Thread(()->{
                System.out.println("-->"+temp);
​
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
​
        }
    }
}

await() 执行 CyclicBarrier 的业务,CyclicBarrier 中的 Runnable 执行一次之后,计数器清零,等待下一次执行。

3、Semaphore:计数信号量

实际开发中主要用来做限流操作,即限制可以访问某些资源的线程数量。

  • 初始化

  • 获取许可

  • 释放许可

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
​
public class SemaphoreTest {
    public static void main(String[] args) {
        //同时只能进5个人
        Semaphore semaphore = new Semaphore(5);
        for (int i = 0; i < 15; i++) {
            new Thread(()->{
                try {
                    //获得许可
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"进店购物");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println(Thread.currentThread().getName()+"出店");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    //释放许可
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

acquire():等待
获取许可,如果没有名额,则等待。

release():释放许可,并且唤醒等待的线程。

推荐阅读