1. Java 并发编程常用类概览
Java 的并发包 java.util.concurrent
(简称 JUC)提供了丰富的工具,主要分为几大类:
类型 | 代表类 | 用途 |
原子类 |
| 无锁地更新单个变量 |
并发集合 |
| 线程安全的集合,性能优于 |
线程池 |
| 统一管理线程,避免频繁创建/销毁 |
同步器 |
| 控制线程间的协作 |
锁 |
| 比 |
2. 原子类(Atomic Classes)
这些类都基于 CAS 实现,用于无锁地更新变量。
类 | 用途 | 示例 |
| 原子整数 |
|
| 原子长整数 |
|
| 原子布尔值 | 标志位,如 |
| 原子引用任意对象 |
|
| 原子长整型数组 | 高性能计数器数组 |
| 带版本号的引用(解决 ABA 问题) | 防止 CAS 被 ABA 欺骗 |
适用场景:计数器、状态标志、ID 生成等简单共享变量。
3. 并发集合(Concurrent Collections)
比 Collections.synchronizedList(...)
性能更好,支持更高并发。
类 | 用途 | 特点 |
| 线程安全的 HashMap | 分段锁或 CAS,读不加锁,写并发高 ✅ 推荐替代 |
| 线程安全的 List | 写操作时复制整个数组,读操作完全无锁,适合读多写少场景(如监听器列表) |
| 阻塞队列 | 线程间安全传递数据,常用于生产者-消费者模式 |
→ | 有界阻塞队列 | 基于数组,容量固定 |
→ | 无界/有界阻塞队列 | 基于链表,吞吐量高 |
→ | 优先级阻塞队列 | 按优先级出队 |
| 高性能无锁队列 | 基于 CAS,适用于高并发场景 |
示例:用 ConcurrentHashMap
存储用户缓存:
private static final ConcurrentHashMap<Long, User> userCache = new ConcurrentHashMap<>();
4. 同步器(Synchronizers)—— 控制线程协作
类 | 用途 | 场景举例 |
| 倒计时门闩:一个或多个线程等待其他线程完成 | 主线程等待 N 个任务全部完成 |
| 循环栅栏:多个线程互相等待,直到都到达某个点 | 多个线程同时开始比赛 |
| 信号量:控制同时访问资源的线程数量 | 限制数据库连接数为 10 |
| 更强大的 | 动态调整参与线程数 |
示例:CountDownLatch
CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; i++) { new Thread(() -> { // 模拟任务 System.out.println("任务完成"); latch.countDown(); // 计数减1 }).start(); } latch.await(); // 等待所有任务完成 System.out.println("所有任务已完成!");
5. 显式锁(Explicit Locks)
比 synchronized
更灵活,支持尝试获取、超时、可中断等。
类 | 用途 | 特点 |
| 可重入锁 | 支持公平锁、尝试获取( |
| 读写锁 | 读读不互斥,读写/写写互斥,适合读多写少场景 |
示例:读写锁
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); private final Map<String, String> cache = new HashMap<>(); // 读操作 public String get(String key) { rwLock.readLock().lock(); try { return cache.get(key); } finally { rwLock.readLock().unlock(); } } // 写操作 public void put(String key, String value) { rwLock.writeLock().lock(); try { cache.put(key, value); } finally { rwLock.writeLock().unlock(); } }
6. 线程池(Thread Pools)
避免频繁创建/销毁线程,提高性能。
类/工具 | 用途 |
| 线程池顶层接口 |
| 可定制的线程池(核心类) |
| 快速创建常见线程池 |
→ | 固定大小线程池 |
→ | 缓存线程池,空闲线程60秒回收 |
→ | 单线程池 |
→ | 支持定时/周期性任务 |
示例:提交任务
ExecutorService executor = Executors.newFixedThreadPool(4); executor.submit(() -> { System.out.println("任务执行中..."); });
7. 总结:如何选择?
需求 | 推荐工具 |
简单计数、状态标志 |
|
高并发映射缓存 |
|
读多写少的列表 |
|
生产者-消费者模型 |
|
等待多个任务完成 |
|
多个线程同步开始 |
|
限制并发数(如连接池) |
|
读多写少的共享资源 |
|
需要灵活锁控制 |
|
异步执行任务 |
|
0条评论
点击登录参与评论