JUC下的辅助工具类

前言

java.util.concurrent包下,存在有几个辅助操作工具类。如CountDownLatch 减法计数器CyclicBarrier 加法计数器Semaphore 信号量

刚听到这几个类,很懵,下面就来说说这三个工具类具体怎么来用。

CountDownLatch 减法计数器

给定初始大小容量,每次线程进行某项操作时调用,容量-1,
等待其中无数据时,继续执行其他操作。

看下面的栗子:

import java.util.concurrent.CountDownLatch;

/**
 * 减法  计数器;用于 必须保证所有线程都执行完后继续其他操作。
 */
public class CountDownTest {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        // 1、计数器对象的创建,并给定计数器初始大小数
        CountDownLatch countDownLatch = new CountDownLatch(6);

        // 开启多个线程执行操作
        for (int i = 1; i <= 6; i++) {
    
    
            new Thread(()->{
    
    
                System.out.println(Thread.currentThread().getName()+" get ticket");
                // 2、每个线程执行某项操作时,将计数器-1
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }

        // 3、等待计数器中的数据门票消耗完
        countDownLatch.await();
        // 4、打印信息
        System.out.println("ticket num 0");
    }
}

执行结果如下所示:
在这里插入图片描述
[发现:]

使用await(),让其他线程执行完成后,会继续等待,有点类似thread 中的 join(),等待所有线程全部执行完成才会继续下面的其他操作。

查看jdk 1.8 开发手册,其中对方法有以下解释:
在这里插入图片描述

CyclicBarrier 加法计数器

上面说到了减法计数器,所以必然也会有加法计数器。其操作类为:CyclicBarrier
看下面的例子:

package demo5_1;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * 加法计数器
 */
public class CyclicBarrierDemo {
    
    
    public static void main(String[] args) {
    
    
        // 创建 10个 大小的  计数器
        //CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10,()->{
    
    
            System.out.println("票售完");
        });

        // 创建多线程
        for (int i = 1; i <= 10 ; i++) {
    
    
            new Thread(()->{
    
    
                // 打印信息
                System.out.println(Thread.currentThread().getName()+" get ticket");
                // 计数器等待
                try {
    
    
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
    
    
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

运行后日志打印信息如下所示:
在这里插入图片描述
[发现:]

1、开始定义了一个加法计数器,采取的构造方式为 public CyclicBarrier(int parties, Runnable barrierAction)
2、每个线程执行某些业务后,调用cyclicBarrier.await(),相当于添加至监控列表中。
3、当设定的容量被占用完,则会触发CyclicBarrier(int parties, Runnable barrierAction)中的Runnable

查看源码await()的执行逻辑:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Semaphore 信号量

信号量工具类,一般用于限定的资源类,
多线程处理时,如果有限定数量的线程全额占用,此时只允许未占用的线程执行等待;
当最初占用的线程释放占用后,后续线程才能获取使用。

类似于下面的逻辑:

Created with Raphaël 2.2.0 线程进入 开始获取座位 座位被占用? 拿到座位 yes no

令牌桶算法逻辑很像哦。比如请求限流!

看图流程依旧还是很抽象,看下面的栗子:

package demo5_1;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 信号量:用于某资源占用,其他处理等待其他线程处理完后才能处理
 */
public class SemphoreDemo {
    
    
    public static void main(String[] args) {
    
    
        // 假设 座位只有3个
        Semaphore semaphore = new Semaphore(3);
        // 创建线程
        for (int i = 1; i <= 12 ; i++) {
    
    
            new Thread(()->{
    
    
                try {
    
    
                    // 获取座位(此处会造成阻塞   必须等待有空位才会分配,即向下执行)
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+" 获取座位");
                    // 假设拿到座位后占用2秒
                    TimeUnit.SECONDS.sleep(2);
                    // 离开座位 原则上应该放在finally中执行 --- 释放资源操作
                    //semaphore.release();
                    //System.err.println(Thread.currentThread().getName()+" 离开座位");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }finally {
    
    
                    // 离开座位 原则上应该放在finally中执行--- 释放资源操作
                    semaphore.release();
                    // 用err只是颜色区分日志打印
                    System.err.println(Thread.currentThread().getName()+" 离开座位");
                }

            },String.valueOf(i)).start();
        }
    }
}

执行后的控制台输出日志如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38322527/article/details/114937513