Java并发编程:JUC核心组件全解析
JUC(Java Util Concurrent) 是 Java 并发编程的核心工具包,提供高性能、线程安全的并发控制组件。自 Java 5 引入,它彻底改变了 Java 多线程开发模式,解决了传统 synchronized
和 wait()/notify()
的局限性。
核心组件概览
类别 | 核心类/接口 | 作用 |
---|---|---|
原子操作类 | AtomicInteger , LongAdder | 无锁线程安全计算 |
锁机制 | ReentrantLock , StampedLock | 替代 synchronized 的显式锁 |
并发集合 | ConcurrentHashMap , CopyOnWriteArrayList | 高性能线程安全容器 |
线程池 | ThreadPoolExecutor , ForkJoinPool | 线程资源管理 |
同步工具 | CountDownLatch , CyclicBarrier | 多线程协调 |
异步编程 | CompletableFuture | 响应式编程支持 |
一、原子操作类(java.util.concurrent.atomic
)
解决非阻塞算法实现,性能远超 synchronized
。
典型使用
// 原子计数器
AtomicInteger counter = new AtomicInteger(0);// 并发递增
IntStream.range(0, 100).parallel().forEach(i -> {counter.incrementAndGet(); // 无锁线程安全操作
});
核心类:
- 基础类型
AtomicInteger
,AtomicLong
,AtomicBoolean
- 引用类型
AtomicReference<User>
,AtomicStampedReference
(解决ABA问题) - 累加器(Java 8+)
LongAdder
(比 AtomicLong 更高并发性能)
二、锁机制(java.util.concurrent.locks
)
1. ReentrantLock
(可重入锁)
Lock lock = new ReentrantLock();void safeIncrement() {lock.lock(); // 显式加锁try {count++;} finally {lock.unlock(); // 必须finally释放}
}
优势:
- 可中断锁:
lockInterruptibly()
- 尝试获取锁:
tryLock(1, TimeUnit.SECONDS)
- 公平锁模式:
new ReentrantLock(true)
2. ReadWriteLock
(读写锁)
ReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock(); // 共享读锁
Lock writeLock = rwLock.writeLock(); // 独占写锁
3. StampedLock
(Java 8 优化锁)
StampedLock lock = new StampedLock();// 乐观读(无锁尝试)
long stamp = lock.tryOptimisticRead();
if (!lock.validate(stamp)) {stamp = lock.readLock(); // 升级为悲观读try { /* 读取操作 */ } finally { lock.unlockRead(stamp); }
}
三、并发集合
1. ConcurrentHashMap
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();// 线程安全的putIfAbsent
map.computeIfAbsent("key", k -> 1);// 并行操作(Java 8+)
map.forEach(2, (k, v) -> System.out.println(k + ":" + v));
特点:
- 分段锁(JDK 7)→ CAS + 红黑树(JDK 8+)
- 高并发下性能接近单线程 HashMap
2. 阻塞队列
队列类型 | 特性 |
---|---|
ArrayBlockingQueue | 有界数组队列 |
LinkedBlockingQueue | 无界/有界链表队列(默认Integer.MAX_VALUE) |
PriorityBlockingQueue | 优先级阻塞队列 |
SynchronousQueue | 无缓冲队列(生产消费必须配对) |
// 生产者-消费者模式
BlockingQueue<Task> queue = new ArrayBlockingQueue<>(10);// 生产者
queue.put(task); // 阻塞直到空间可用// 消费者
Task task = queue.take(); // 阻塞直到元素可用
四、线程池(java.util.concurrent
)
1. ThreadPoolExecutor
ExecutorService executor = new ThreadPoolExecutor(4, // 核心线程数10, // 最大线程数60, // 空闲线程存活时间(秒)TimeUnit.SECONDS,new ArrayBlockingQueue<>(100), // 工作队列new ThreadFactoryBuilder().setNameFormat("worker-%d").build(),new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
2. Executors
工厂方法
// 固定线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(4);// 工作窃取池(Java 7+)
ExecutorService workStealingPool = Executors.newWorkStealingPool();// 定时任务池
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
五、同步工具类
1. CountDownLatch
(倒计时门闩)
CountDownLatch latch = new CountDownLatch(3);// 多个线程完成任务
executor.execute(() -> {doWork();latch.countDown(); // 计数器-1
});latch.await(); // 阻塞直到计数器归零
System.out.println("All tasks completed");
2. CyclicBarrier
(循环屏障)
CyclicBarrier barrier = new CyclicBarrier(3, () -> {System.out.println("All threads reached barrier");
});IntStream.range(0, 3).forEach(i -> executor.execute(() -> {prepareWork();barrier.await(); // 等待其他线程continueWork();
}));
3. Semaphore
(信号量)
Semaphore semaphore = new Semaphore(3); // 允许3个并发void accessResource() {semaphore.acquire(); // 获取许可try {useResource();} finally {semaphore.release(); // 释放许可}
}
六、异步编程(CompletableFuture
,Java 8+)
CompletableFuture.supplyAsync(() -> fetchData()) // 异步任务.thenApply(data -> transform(data)) // 同步转换.thenAcceptAsync(result -> save(result), ioPool) // 异步消费.exceptionally(ex -> handleError(ex)); // 异常处理
核心操作:
- 组合:
thenCompose()
,thenCombine()
- 并行:
allOf()
,anyOf()
- 超时控制:
orTimeout()
,completeOnTimeout()
(Java 9+)
JUC 设计哲学
- 降低锁粒度
分段锁(ConcurrentHashMap)、读写分离(ReadWriteLock) - 无锁化编程
CAS 操作(AtomicXXX)、LongAdder - 线程资源复用
线程池机制避免频繁创建/销毁 - 协调而非阻塞
CountDownLatch/CyclicBarrier 替代 wait/notify
最佳实践
- 优先使用并发集合
替代Collections.synchronizedXXX()
- 线程池资源管理
禁止使用Executors.newCachedThreadPool()
(易致 OOM) - 锁使用规范
Lock lock = ...; lock.lock(); try { /* 临界区 */ } finally { lock.unlock(); } // 必须finally释放
- 异步编程陷阱
CompletableFuture 回调链需处理异常
性能对比(示例)
操作 | synchronized | ReentrantLock | AtomicLong |
---|---|---|---|
1000万次递增 (4线程) | 1200 ms | 850 ms | 210 ms |
内存占用 | 高 | 中 | 低 |
可中断性 | 不支持 | 支持 | 不适用 |
测试环境:JDK 17, Apple M1 Pro
学习路线
- 基础:
AtomicInteger
→ReentrantLock
→ConcurrentHashMap
- 进阶:
ThreadPoolExecutor
→CountDownLatch
→CompletableFuture
- 高级:
ForkJoinPool
→StampedLock
→Phaser
(阶段同步器)
推荐资源:
- 《Java Concurrency in Practice》(并发编程圣经)
- JUC 源码(Doug Lea 大师之作)
- Java 官方并发教程:Oracle Concurrency
重要提示:JUC 解决了并发难题,但也引入新复杂度。务必通过
jstack
、VisualVM
等工具分析线程状态,避免死锁和资源耗尽。