温岭网站建设联系电话泸州市建设局网站
一、为什么引入JUC
Java 并发工具包(java.util.concurrent,简称 JUC)的引入是为了解决多线程编程中的复杂性、性能瓶颈和安全性问题。在原生 Java 线程模型(Thread、synchronized、wait/notify)基础上,JUC 提供了更高效、更灵活的工具,核心解决以下关键问题:
1. 原生同步机制的局限性
synchronized性能问题:
原生synchronized是重量级锁,在竞争激烈时会导致线程频繁挂起/唤醒,引发上下文切换开销。JUC 提供了可重入锁(ReentrantLock),支持:- 非阻塞尝试获取锁(
tryLock()) - 可中断锁(
lockInterruptibly()) - 公平锁选项(减少线程饥饿)
 - 更细粒度的锁控制(配合 
Condition实现多条件等待)。 
- 非阻塞尝试获取锁(
 wait/notify难以维护:
在多条件等待场景中(如生产者-消费者),wait/notify易引发错误(如虚假唤醒)。JUC 的Condition接口 支持多条件队列,简化复杂同步逻辑。
2. 线程安全容器的性能瓶颈
Collections.synchronizedXXX效率低:
通过同步包装的集合(如synchronizedList)使用粗粒度锁,所有操作串行化。JUC 提供了高性能并发容器:ConcurrentHashMap:分段锁/无锁 CAS 实现高并发读/写。CopyOnWriteArrayList:读无锁,写时复制(适合读多写少)。BlockingQueue(如ArrayBlockingQueue,LinkedBlockingQueue):线程安全的阻塞队列,简化生产者-消费者模型。
3. 复杂并发任务的协作困难
原生线程 API 难以协调多线程任务,JUC 提供以下工具:
CountDownLatch:
让主线程等待多个子任务完成(如启动初始化)。CyclicBarrier:
让一组线程相互等待,直到所有线程到达屏障点(如多阶段计算)。Semaphore:
控制同时访问资源的线程数(如限流)。Phaser:
更灵活的分阶段屏障(替代CountDownLatch和CyclicBarrier)。
4. 线程池管理的复杂性
- 原生 
Thread开销大:
频繁创建/销毁线程消耗资源。JUC 提供Executor框架:- 线程池(
ThreadPoolExecutor,ScheduledThreadPoolExecutor)复用线程资源。 - 支持任务提交(
submit())、生命周期管理、拒绝策略等。 - 避免手动管理线程。
 
 - 线程池(
 
5. 原子操作的实现成本
volatile不够灵活:
volatile只保证可见性,不保证复合操作原子性。JUC 的atomic包(如AtomicInteger,AtomicReference)通过 CAS(无锁算法) 实现高效原子操作,避免锁开销。
6. 避免死锁和提高可扩展性
- 锁分离与无锁算法:
如ConcurrentHashMap分段锁减少竞争,CopyOnWriteArrayList读操作无锁,提升高并发场景性能。 - 非阻塞数据结构:
例如ConcurrentLinkedQueue使用 CAS 实现无锁队列,避免死锁。 
代码示例对比
原生 synchronized vs ReentrantLock
 
// 原生 synchronized
synchronized(lock) {while (!condition) lock.wait();// 操作资源lock.notifyAll();
}// JUC ReentrantLock + Condition
lock.lock();
try {while (!condition) condition.await();// 操作资源condition.signal();
} finally {lock.unlock();
}
 
ReentrantLock 支持超时、中断,且 Condition 可细分等待条件(如生产者/消费者独立队列)。
二、JUC 工具包核心组件
1. Lock 框架 (java.util.concurrent.locks)
-  
ReentrantLock
Lock lock = new ReentrantLock(true); // 公平锁 lock.lockInterruptibly(); // 可中断获取锁 try {// 临界区 } finally {lock.unlock(); } -  
ReadWriteLock
ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); rwLock.readLock().lock(); // 读锁共享 rwLock.writeLock().lock(); // 写锁排他 -  
Condition
Condition condition = lock.newCondition(); condition.await(1, TimeUnit.SECONDS); // 超时等待 condition.signal(); // 唤醒线程 
2. 原子类 (java.util.concurrent.atomic)
- 实现原理:CAS (Unsafe.compareAndSwapXXX)
// HotSpot 源码片段 (atomic.cpp) jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest...) {return __sync_val_compare_and_swap(dest, compare_value, exchange_value); } - 示例
AtomicInteger atomicInt = new AtomicInteger(); atomicInt.updateAndGet(x -> x * 2); // 原子更新// LongAdder 分段计数优化高并发 LongAdder adder = new LongAdder(); adder.add(10); 
3. 并发容器
| 容器类 | 特性 | 实现原理 | 
|---|---|---|
ConcurrentHashMap | 分段锁/CAS+synchronized | JDK8: Node数组+链表/红黑树 | 
CopyOnWriteArrayList | 写时复制 | 写操作加锁复制新数组 | 
ConcurrentLinkedQueue | 无锁队列 | CAS更新头尾节点 | 
BlockingQueue | 阻塞操作 | Condition等待队列 | 
// ConcurrentHashMap 使用示例
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key", k -> 1); // 原子操作
 
4. 同步工具类
-  
CountDownLatch:一次性屏障
CountDownLatch latch = new CountDownLatch(3); latch.await(); // 主线程等待 latch.countDown(); // 任务线程完成 -  
CyclicBarrier:可重用栅栏
CyclicBarrier barrier = new CyclicBarrier(5, () -> System.out.println("All threads arrived")); barrier.await(); // 线程同步点 -  
Semaphore:资源许可证
Semaphore sem = new Semaphore(5); // 资源池容量 sem.acquire(); // 获取许可 sem.release(); // 释放许可 -  
Exchanger:线程间数据交换
Exchanger<String> exchanger = new Exchanger<>(); String data = exchanger.exchange("Data"); // 阻塞等待交换 
5. 线程池框架
-  
核心参数
new ThreadPoolExecutor(corePoolSize, // 核心线程数maxPoolSize, // 最大线程数keepAliveTime, // 空闲线程存活时间TimeUnit.SECONDS,new LinkedBlockingQueue(100), // 工作队列new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略 ) -  
ForkJoinPool 工作窃取算法
class FibTask extends RecursiveTask<Integer> {protected Integer compute() {if (n <= 1) return n;FibTask f1 = new FibTask(n-1);f1.fork(); // 拆分子任务return f2.compute() + f1.join();} } 
三、深入源码解析
1. AQS (AbstractQueuedSynchronizer) 机制
// ReentrantLock 获取锁源码片段
final boolean nonfairTryAcquire(int acquires) {if (compareAndSetState(0, 1)) { // CAS尝试设置statesetExclusiveOwnerThread(current);return true;}return false;
}// 等待队列入队操作 (CLH队列)
private Node enq(Node node) {for (;;) {Node t = tail;if (t == null) // 初始化队列if (compareAndSetHead(new Node()))tail = head;else {node.prev = t;if (compareAndSetTail(t, node)) {t.next = node;return t;}}}
}
 
2. ConcurrentHashMap 扩容设计
// 扩容时数据迁移 (transfer方法)
while (nextTab != null && transferIndex > 0) {synchronized (f) { // 锁住桶头节点// 将链表/树拆分成高位和低位链表if (fh >= 0) {Node<K,V> loHead = null, loTail = null;Node<K,V> hiHead = null, hiTail = null;// ...数据迁移操作...}}
}
 
3. FutureTask 状态机
// FutureTask 状态转换
private static final int NEW          = 0; // 新建
private static final int COMPLETING   = 1; // 执行中
private static final int NORMAL       = 2; // 正常结束
private static final int EXCEPTIONAL  = 3; // 异常结束
private static final int CANCELLED    = 4; // 已取消
private static final int INTERRUPTING = 5; // 中断中
private static final int INTERRUPTED  = 6; // 已中断
 
四、高级特性与最佳实践
-  
避免死锁的技巧
- 锁排序:按固定顺序获取锁
 - 使用 
tryLock()带超时机制 
if (lock1.tryLock(1, SECONDS)) {try {if (lock2.tryLock(1, SECONDS)) {try { /* 业务操作 */ } finally { lock2.unlock(); }}} finally { lock1.unlock(); } } -  
JMM(Java Memory Model)原则
- Happens-Before 规则: 
- 程序顺序规则
 - volatile变量规则
 - 传递性规则
 
 
 - Happens-Before 规则: 
 -  
性能优化
- 用 LongAdder 替代 AtomicLong 高并发计数
 - 避免锁升级:优先用 volatile + CAS
 - ConcurrentHashMap.size() vs mappingCount()
 
 
五、Java 并发发展
- Java 19 虚拟线程(Virtual Threads)
 - Java 21 结构化并发
 - Project Loom 的协程实现
 
学习路径建议:
- 掌握基础锁机制 → 2. 熟练使用 JUC 工具类 → 3. 阅读源码理解原理 → 4. 通过 Arthas 等工具实战调试 → 5. 学习性能调优方案
 
六、总结
JUC 的核心价值:
- 提升性能:通过无锁算法(CAS)、细粒度锁、并发容器减少竞争。
 - 简化复杂性:标准化工具(如线程池、
BlockingQueue)替代手写复杂同步逻辑。 - 增强安全性:避免死锁、竞争条件,提供更可靠的线程协作机制。
 - 可扩展性:支持高并发场景(如百万级连接的服务端)。
 
理解并发工具包需要结合底层硬件知识(CPU缓存、内存屏障)和操作系统原理(线程调度、同步原语),通过工具包源码的学习能帮助开发者编写高性能、线程安全的并发程序。
