news 2026/10/10 16:27:46

第四章 JUC 常见并发工具类(java.util.concurrent,面试核心)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第四章 JUC 常见并发工具类(java.util.concurrent,面试核心)

定位:JUC是Java标准库提供的并发编程工具包,包含任务封装、可重入锁、原子类、线程池、同步工具等,比原生synchronized更灵活、功能更强。


1. Callable 接口 + FutureTask

解决的问题

Runnable的void run()没有返回值,也不能抛出受检异常;如果需要线程执行完带回结果,原生写法需要自己写同步、等待、结果类,代码繁琐易错。

Callable 接口(适合于想让某个线程执行一个逻辑,并且返回结果的时候相比之下Runnable不关注结果)

public interface Callable<V> { V call() throws Exception; }
  • 带泛型V,表示返回值的类型
  • call()方法可以返回结果,也可以抛出异常

FutureTask

Callable不能直接传给Thread执行,需要用FutureTask包装。

  • 作用:保存Callable的执行结果;主线程可以通过它阻塞等待任务完成并获取结果。
  • 通俗比喻:点麻辣烫,后厨开始做,前台给你一张小票(FutureTask),随时可以凭小票看做好了没。

完整代码示例

// 定义带返回值的任务:计算1~1000的和 Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { int sum = 0; for (int i = 1; i <= 1000; i++) { sum += i; } return sum; } }; FutureTask<Integer> futureTask = new FutureTask<>(callable); new Thread(futureTask).start(); // 主线程阻塞等待,直到任务完成拿到结果 //此处的get就能获取到callable里面的 返回结果 //由于线程是并发执行的,执行到主线程的get的时候,t线程可能还没有执行完 //没有执行完的话就会阻塞 Integer result = futureTask.get(); System.out.println(result);

面试核心点

  • Runnable:无返回值,不抛出受检异常
  • Callable:有返回值,可抛出异常,必须搭配FutureTask使用
  • futureTask.get():阻塞等待任务执行完成,获取返回值

2. ReentrantLock 可重入互斥锁

和synchronized定位相同,都是实现线程互斥,保证线程安全;但ReentrantLock是Java类实现,功能更灵活。

基础用法

ReentrantLock lock = new ReentrantLock(); lock.lock(); // 加锁,拿不到锁就死等 try { // 临界区业务代码 } finally { lock.unlock(); // 必须手动解锁,写在finally防止异常遗漏 }

增强功能

  1. tryLock(long timeout):尝试加锁,等待指定时间还拿不到锁就放弃,不会死等。
  2. 公平锁支持:构造方法传入true即可开启公平锁,遵守先来后到。
    ReentrantLock fairLock = new ReentrantLock(true); // 公平锁
  3. 精准唤醒:搭配Condition类,可以指定唤醒某个/某组等待线程;而synchronized的notify()只能随机唤醒一个。

synchronized vs ReentrantLock 对比(面试必背)

维度synchronizedReentrantLock
实现层面JVM关键字,底层C++实现JDK标准库类,Java代码实现
锁释放退出同步块自动释放必须手动调用unlock
加锁行为拿不到锁就死等lock()死等;tryLock可超时放弃
公平性只能非公平锁默认非公平,可手动开启公平锁
等待唤醒wait/notify,随机唤醒Condition,可精准唤醒指定线程
锁类型可重入锁可重入锁

选型建议

  • 锁竞争不激烈、代码简单:优先用synchronized,自动释放不易出错
  • 锁竞争激烈、需要超时放弃、公平锁、精准唤醒:用ReentrantLock

3. 原子类(java.util.concurrent.atomic)

原理

内部基于CAS + volatile实现,不需要加锁就能完成线程安全的数值操作,性能远高于synchronized。

常见原子类

  • AtomicBoolean:原子布尔值
  • AtomicInteger:原子整数
  • AtomicLong:原子长整型
  • AtomicReference:原子引用对象
  • AtomicStampedReference:带版本号的原子引用,解决ABA问题

AtomicInteger 常用方法

方法作用对应普通操作
getAndIncrement()返回旧值,再自增i++
incrementAndGet()先自增,返回新值++i
getAndDecrement()返回旧值,再自减i--
decrementAndGet()先自减,返回新值--i
addAndGet(int delta)加上delta,返回新值i += delta

面试考点

AtomicInteger底层是CAS自旋实现的乐观锁,不需要重量级锁,高并发下性能优于synchronized。


4. 线程池

核心思想

线程创建销毁比进程轻量,但频繁创建销毁依然有开销。线程池提前创建一批线程复用,任务来了直接分配线程执行,任务完成线程不销毁,放回池中等待下一个任务。

Executors 工厂类(快捷创建线程池)

Executors是线程池工厂类,提供4种常用线程池,底层都是封装ThreadPoolExecutor。

工厂方法特点
newFixedThreadPool(n)固定线程数量的线程池
newCachedThreadPool()线程数动态伸缩,空闲线程缓存复用
newSingleThreadExecutor()只有一个线程,任务串行执行
newScheduledThreadPool(n)支持延迟、定时执行任务,多线程版定时器

注意:生产环境不推荐直接用Executors,因为部分线程池队列无界、最大线程数无界,高并发下容易OOM。

ThreadPoolExecutor 七大核心参数(面试必考)

可以理解为开一家公司:

  1. corePoolSize核心线程数:正式员工,常驻不辞退
  2. maximumPoolSize最大线程数:正式员工 + 临时工的总上限
  3. keepAliveTime空闲存活时间:临时工空闲多久就被辞退
  4. TimeUnit unit:时间单位
  5. BlockingQueue<Runnable> workQueue:阻塞任务队列,存放等待执行的任务
  6. ThreadFactory threadFactory:线程工厂,统一创建线程,可自定义线程名称
  7. RejectedExecutionHandler handler:拒绝策略,任务超过承载时的处理方式

四种拒绝策略

  1. AbortPolicy【默认】:直接抛出RejectedExecutionException异常
  2. CallerRunsPolicy:由提交任务的线程自己执行这个任务
  3. DiscardOldestPolicy:丢弃队列中排队最久的任务,再尝试提交新任务
  4. DiscardPolicy:直接丢弃新来的任务,不抛异常

线程池执行流程(必背)

  1. 提交任务 → 核心线程未满 → 创建核心线程执行任务
  2. 核心线程已满 → 任务进入阻塞队列排队
  3. 队列也满了 → 创建非核心(临时)线程执行任务
  4. 总线程数达到最大线程数 → 触发拒绝策略
  5. 任务高峰过后,非核心线程空闲超过keepAliveTime→ 销毁回收,核心线程保留

5. Semaphore 信号量

锁本质也是一种特殊的信号量,加锁操作p操作,1->0 ,解锁操作V操作0->1 (二元信号量)

核心作用

表示可用资源的个数,本质是一个原子计数器,控制同时访问资源的最大线程数。

PV操作

  • acquire()P操作:申请一个资源,计数器-1;计数器为0则阻塞等待
  • release()V操作:释放一个资源,计数器+1,唤醒等待的线程

通俗比喻(PDF原文)

停车场剩余车位牌。车开进去车位-1,开出来车位+1;车位为0时,门口的车等待。

代码示例

// 初始4个许可,最多4个线程同时执行 Semaphore semaphore = new Semaphore(4); Runnable task = () -> { try { semaphore.acquire(); // 申请资源 System.out.println("获取到资源,执行任务"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); // 释放资源 } }; // 启动20个线程,最多同时4个运行 for (int i = 0; i < 20; i++) { new Thread(task).start(); }

适用场景

限流、控制并发数、共享资源池管理。开发中需要申请资源的场景


6. CountDownLatch 倒计时锁存器

核心作用

等待N个任务全部执行完成,主线程再继续往下走。

核心方法

  1. CountDownLatch(int count):构造方法,指定需要等待的任务数量
  2. countDown():每个任务执行完调用一次,计数器-1
  3. await():主线程调用,阻塞等待,直到计数器减到0

通俗比喻

跑步比赛:10个选手就位,枪响同时出发;必须等所有选手都冲过终点,才能公布成绩。

代码示例

// 等待10个任务全部完成 CountDownLatch latch = new CountDownLatch(10); Runnable task = () -> { try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) {} latch.countDown(); // 任务完成,计数减一 }; for (int i = 0; i < 10; i++) { new Thread(task).start(); } latch.await(); // 主线程阻塞,直到所有任务完成 System.out.println("全部任务执行完毕");

适用场景

多任务并行执行,最后统一汇总结果;主流程等待多个子任务全部完成。


第四章 面试高频总结

  1. Callable带返回值,FutureTask用来接收结果,get()阻塞等待。
  2. ReentrantLock是可重入锁,支持超时、公平锁、精准唤醒,需要手动解锁。
  3. 原子类基于CAS实现,无锁线程安全,适合高并发数值操作。
  4. 线程池7大参数、4种拒绝策略、执行流程是面试必考题。
  5. Semaphore控制最大并发数,CountDownLatch等待多任务全部完成。

第四章的内容就全部梳理完了,覆盖了PDF里所有工具类的定义、用法、比喻、场景和面试考点。确认理解后,我们进入第五章线程安全集合类的详细讲解。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 16:27:12

人脸识别系统毕设全流程:从数据集采集到门禁落地避坑指南

简介&#xff1a;面向毕业设计场景的人脸识别系统资源包&#xff0c;系统覆盖计算机视觉、图像处理、模式识别与深度学习多条技术线。包内不仅提供从开题报告、摘要到详细设计说明的完整文档&#xff0c;还包含可运行的C工程与人脸数据库&#xff0c;内置人脸检测、特征提取与匹…

作者头像 李华
网站建设 2026/10/10 16:22:01

Java集合Set详解:HashSet去重、LinkedHashSet保序与TreeSet排序

1. 整体设计与思路拆解&#xff1a;Set到底在解决什么问题聊到Java集合&#xff0c;很多人第一反应是ArrayList、HashMap这类“用得最勤快”的容器&#xff0c;Set往往被一笔带过。但真正到了面试或者线上排查问题的时候&#xff0c;你会发现Set才是最容易翻车的那一个。不是说…

作者头像 李华
网站建设 2026/10/10 16:21:58

动态目标三维重构在要地防卫、人群异常行为研判中的应用

摘要要地防卫涵盖党政核心驻地、军事营区、枢纽场馆、战备设施、涉密点位等极高等级安防场景&#xff0c;核心防控对象包含外来入侵目标、近距离抵近人员、违规闯入车辆及高密度流动人群&#xff0c;具备防卫等级高、人员车流密集、场景开放性强、异常态势隐蔽、突发风险蔓延快…

作者头像 李华
网站建设 2026/10/10 16:20:55

RSNA肺炎检测数据集:VOC与YOLO双格式解析及训练前避坑指南

简介&#xff1a;RSNA肺炎检测数据集面向医学影像目标检测方向的学习者与开发者&#xff0c;围绕RSNA胸部影像场景整理&#xff0c;数据规模为6012张图片、单一类别meat、9555个目标框&#xff0c;适合直接用于YOLO、Faster R-CNN等主流检测框架的训练与评估。数据提供Pascal V…

作者头像 李华
网站建设 2026/10/10 16:18:29

两个正序数组找中位数:二分排除法与划分数组法详解

我一开始接触这道题的时候&#xff0c;觉得它就是个简单的“归并排序取中间值”问题&#xff0c;不就是把两个数组合并起来&#xff0c;然后按下标取值吗&#xff1f;直到我读到题目里那个O(log(mn))的时间复杂度要求&#xff0c;才意识到事情没那么简单。这道题是数组二分操作…

作者头像 李华
网站建设 2026/10/10 16:17:28

动物疫病防控压力大?动物检疫 LIMS 系统,解决基层实验室痛点

随着社会的发展和人们生活水平的提高&#xff0c;人们对食品质量的要求也越来越高。食品安全问题一直是社会关注的焦点&#xff0c;而动物检疫作为保障食品安全的重要环节&#xff0c;其重要性不言而喻。北京盛元广通科技有限公司推出的动物检疫实验室管理系统&#xff0c;正是…

作者头像 李华