【Java-多线程】我们常说的 JUC 是指什么?
JUC 是 **Java Util Concurrent** 的缩写,是 Java 5 开始提供的并发编程工具包。它像一把瑞士军刀,提供了比传统 synchronized 更灵活的并发控制手段。
·
一、JUC 核心概念解析
JUC 是 Java Util Concurrent 的缩写,是 Java 5 开始提供的并发编程工具包。它像一把瑞士军刀,提供了比传统 synchronized 更灵活的并发控制手段。
1.1 核心组件构成
1.2 与传统同步对比
// 传统方式
synchronized(obj) {
// 临界区代码
}
// JUC方式
Lock lock = new ReentrantLock();
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
关键差异:
- 可中断锁(避免死锁)
- 公平锁机制
- 多条件变量(Condition)
- 锁等待超时功能
二、核心组件详解
2.1 Lock 体系
ReentrantLock 就像更智能的门禁系统:
Lock lock = new ReentrantLock(true); // 公平锁
Condition notEmpty = lock.newCondition();
public void consume() {
lock.lock();
try {
while(queue.isEmpty()) {
notEmpty.await(); // 精准等待
}
// 消费数据...
} finally {
lock.unlock();
}
}
2.2 原子类原理(CAS 机制)
使用 CPU 级别的 Compare-And-Swap 指令:
AtomicInteger count = new AtomicInteger(0);
// 线程安全的自增
count.incrementAndGet();
CAS 流程图:
三、典型应用场景
3.1 高并发计数器
// 错误示范(普通变量)
private int count = 0;
// 正确方案
private AtomicInteger count = new AtomicInteger(0);
public void safeIncrement() {
count.incrementAndGet();
}
3.2 资源池管理(Semaphore)
像高速公路收费站:
Semaphore semaphore = new Semaphore(5); // 5个许可
void useResource() {
semaphore.acquire();
try {
// 使用共享资源
} finally {
semaphore.release();
}
}
四、常见面试题精解
题目:AQS(AbstractQueuedSynchronizer)工作原理?
解析:
- 核心数据结构:CLH 队列(双向链表)
- 状态变量:volatile int state
- 关键方法:
- acquire():获取资源
- release():释放资源
类比说明:
想象医院挂号系统:
- state 表示剩余号源数
- CLH 队列是排队患者
- CAS 操作是自动叫号系统
五、思维导图生成
JUC 全称是 Java Util Concurrent,是 Java 并发编程的核心工具包,包含三大核心内容:
一、JUC 核心组件
-
Lock 体系
ReentrantLock
显式锁(对标synchronized
)
Lock lock = new ReentrantLock(); lock.lock(); try { // 临界区 } finally { lock.unlock(); }
ReadWriteLock
读写分离锁(提升并发读性能)
-
原子类
AtomicInteger
/AtomicReference
等(基于 CAS 的无锁并发)
AtomicInteger count = new AtomicInteger(0); count.incrementAndGet(); // 线程安全的自增操作
-
并发集合
ConcurrentHashMap
(分段锁实现)CopyOnWriteArrayList
(写时复制集合)
-
线程池
ThreadPoolExecutor
核心线程池实现Executors
工厂类(但生产环境慎用)
-
同步工具
CountDownLatch
(倒计时门闩)CyclicBarrier
(循环栅栏)Semaphore
(信号量)
二、实现原理
-
AQS(AbstractQueuedSynchronizer)
- 通过
state
变量 + CLH 队列实现锁机制
- 通过
-
CAS(Compare And Swap)
- CPU 原子指令实现无锁更新(
sun.misc.Unsafe
类)
- CPU 原子指令实现无锁更新(
-
内存屏障
volatile
关键字保证可见性happens-before
原则确保指令顺序
三、生产案例
-
电商库存扣减
// 使用 AtomicInteger 保证库存扣减原子性 AtomicInteger stock = new AtomicInteger(100); public boolean reduceStock() { while (true) { int current = stock.get(); if (current <= 0) return false; if (stock.compareAndSet(current, current-1)) { return true; } } }
-
秒杀系统限流
// 使用 Semaphore 控制并发数 Semaphore semaphore = new Semaphore(500); // 允许 500 并发 public void seckill() { if (!semaphore.tryAcquire()) { throw new RuntimeException("秒杀已满"); } try { // 处理秒杀逻辑 } finally { semaphore.release(); } }
四、注意事项
-
死锁预防
- 避免嵌套锁
- 使用
tryLock()
设置超时时间
-
性能调优
- 合理设置线程池参数(核心/最大线程数、队列类型)
- 优先使用并发集合替代同步集合
-
线程安全设计
- 状态变量尽量使用 final 修饰
- 优先使用不可变对象
知识图谱
Java面试题解析:JUC详解
一、什么是JUC?
JUC是java.util.concurrent
工具包的简称,是Java 5开始引入的并发编程工具包,包含:
- 原子类(AtomicInteger等)
- 并发集合(ConcurrentHashMap等)
- 锁机制(ReentrantLock等)
- 线程池(ThreadPoolExecutor等)
- 同步工具(CountDownLatch等)
案例:传统售票问题
// 线程不安全的实现 class Ticket { private int count = 100; public void sell() { if(count > 0) { System.out.println(Thread.currentThread().getName() + "卖出票号" + count--); } } } // 使用JUC改进 class SafeTicket { private AtomicInteger count = new AtomicInteger(100); private ReentrantLock lock = new ReentrantLock(); public void sell() { lock.lock(); try { if(count.get() > 0) { System.out.println(Thread.currentThread().getName() + "卖出票号" + count.getAndDecrement()); } } finally { lock.unlock(); } } }
二、核心组件解析
1. Lock体系
ReentrantLock
vssynchronized
- 可中断锁
- 尝试获取锁(tryLock)
- 公平锁/非公平锁
2. 原子类原理
CAS机制(Compare And Swap):
public final int getAndIncrement() {
int prev, next;
do {
prev = get(); // 当前值
next = prev + 1; // 期望值
} while (!compareAndSet(prev, next));
return prev;
}
3. 线程池参数
三、高频面试问题
- AQS原理:通过CLH队列管理线程,state变量控制资源状态
- ThreadLocal内存泄漏:使用弱引用+及时remove
- ConcurrentHashMap实现:JDK7分段锁 vs JDK8 CAS+synchronized
- 死锁排查:jstack查看线程状态
四、最佳实践建议
- 优先使用并发集合而非同步集合
- 使用ThreadPoolExecutor而非Executors创建线程池
- 合理设置锁粒度(如读写锁分离)
- 使用CompletableFuture处理异步任务
JUC知识体系总结
更多推荐
所有评论(0)