面试必问! JUC 常用 4 大并发工具类是哪几个?

点击上方“Java基基”,选择“设为星标”
做积极的人,而不是积极废人!
每天14:00更新文章,每天掉亿点点头发...
源码精品专栏
来源:/-dance/
p/.html
「什么是JUC?」
JUC 就是 java.util. 包,这个包俗称 JUC,里面都是解决并发问题的一些东西 。
该包的位置位于 java 下面的 rt.jar 包下面
「4大常用并发工具类:」
基于Boot +Plus + Vue &实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能 。
项目地址:
「:」
,俗称闭锁,作用是类似加强版的 Join,是让一组线程等待其他的线程完成工作以后才执行 。
就比如在启动框架服务的时候,我们主线程需要在环境线程初始化完成之后才能启动,这时候我们就可以实现使用来完成 。
/*** Constructs a {@code CountDownLatch} initialized with the given count.** @param count the number of times {@link #countDown} must be invoked*before threads can pass through {@link #await}* @throws IllegalArgumentException if {@code count} is negative*/public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync = new Sync(count);}
在源码中可以看到,创建时,需要传入一个 int 类型的参数,将决定在执行次扣减之后,等待的线程被唤醒 。
等待的线程被唤醒
通过这个类图就可以知道其实并没有多少东西 。
方法介绍:
里面的 Sync 是一个内部类,外面的方法其实都是操作这个内部类的,这个内部类继承了 AQS,实现的标准方法,AQS 将在后面的章节写 。
Sync 是一个内部类
主线程中创建 (3),然后主线程 await 阻塞,然后线程 A,B,C 各自完成了任务,调用了 ,之后,每个线程调用一次计数器就会减一,初始是 3,然后 A 线程调用后变成 2,B 线程调用后变成 1,C 线程调用后,变成 0,这时就会唤醒正在 await 的主线程,然后主线程继续执行 。
说一千道一万,不如代码写几行,上代码:
休眠工具类,之后的代码都会用到
package org.dance.tools;import java.util.concurrent.TimeUnit;/*** 类说明:线程休眠辅助工具类*/public class SleepTools {/*** 按秒休眠* @param seconds 秒数*/public static final void second(int seconds) {try {TimeUnit.SECONDS.sleep(seconds);} catch (InterruptedException e) {}}/*** 按毫秒数休眠* @param seconds 毫秒数*/public static final void ms(int seconds) {try {TimeUnit.MILLISECONDS.sleep(seconds);} catch (InterruptedException e) {}}}package org.dance.day2.util;import org.dance.tools.SleepTools;import java.util.concurrent.CountDownLatch;/*** CountDownLatch的使用,有五个线程,6个扣除点* 扣除完成后主线程和业务线程,才能执行工作*扣除点一般都是大于等于需要初始化的线程的* @author ZYGisComputer*/public class UseCountDownLatch {/*** 设置为6个扣除点*/static CountDownLatch countDownLatch = new CountDownLatch(6);/*** 初始化线程*/private static class InitThread implements Runnable {@Overridepublic void run() {System.out.println("thread_" + Thread.currentThread().getId() + " ready init work .....");// 执行扣减 扣减不代表结束countDownLatch.countDown();for (int i = 0; i < 2; i++) {System.out.println("thread_" + Thread.currentThread().getId() + ".....continue do its work");}}}/*** 业务线程*/private static class BusiThread implements Runnable {@Overridepublic void run() {// 业务线程需要在等初始化完毕后才能执行try {countDownLatch.await();for (int i = 0; i < 3; i++) {System.out.println("BusiThread " + Thread.currentThread().getId() + " do business-----");}} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {// 创建单独的初始化线程new Thread(){@Overridepublic void run() {SleepTools.ms(1);System.out.println("thread_" + Thread.currentThread().getId() + " ready init work step 1st.....");// 扣减一次countDownLatch.countDown();System.out.println("begin stop 2nd.....");SleepTools.ms(1);System.out.println("thread_" + Thread.currentThread().getId() + " ready init work step 2nd.....");// 扣减一次countDownLatch.countDown();}}.start();// 启动业务线程new Thread(new BusiThread()).start();// 启动初始化线程for (int i = 0; i