Java JUC(java.util.concurrent
)及并发编程相关的核心概念/关键字非常多,按常用程度和重要性排序如下,附核心作用说明:
一、基础核心概念(并发编程基石)
-
volatile
- 作用:保证变量的可见性(多线程间变量值同步)和禁止指令重排(如单例模式双重检查),但不保证原子性。
- 场景:状态标记(如
boolean isRunning
)、双重检查锁(DCL)。
-
CAS(Compare-And-Swap)
- 作用:硬件级原子操作(比较并交换),通过
Unsafe
类实现,是无锁编程的核心(如原子类、自旋锁)。 - 原理:
CAS(V, A, B)
,若内存值V
等于预期值A
,则更新为B
,否则失败。 - 问题:ABA问题(可通过
AtomicStampedReference
解决)。
- 作用:硬件级原子操作(比较并交换),通过
-
AQS(AbstractQueuedSynchronizer)
- 作用:JUC同步工具的底层框架,通过状态变量(state) 和双向阻塞队列实现锁的获取/释放。
- 衍生工具:
ReentrantLock
、Semaphore
、CountDownLatch
等均基于AQS。
二、锁与同步机制(线程安全控制)
-
Lock
接口及实现类- 核心实现:
ReentrantLock
(可重入锁)、ReentrantReadWriteLock
(读写锁)、StampedLock
(乐观读锁)。 - 作用:替代
synchronized
,提供更灵活的锁控制(如可中断、超时获取、公平锁)。 - 场景:高并发读写分离(
ReentrantReadWriteLock
)、需要超时释放的场景。
- 核心实现:
-
synchronized
- 作用:内置锁,保证方法/代码块的原子性、可见性、有序性,JDK 6后优化为(偏向锁→轻量级锁→重量级锁)升级机制。
- 特点:使用简单(自动释放锁),但灵活性低于
Lock
。
-
wait()
/notify()
/notifyAll()
- 作用:
Object
类的方法,配合synchronized
实现线程间协作(等待/唤醒)。 - 注意:必须在
synchronized
块中调用,否则抛IllegalMonitorStateException
。
- 作用:
-
Condition
- 作用:
Lock
对应的条件变量,替代wait()
/notify()
,支持多条件队列(一个锁可关联多个Condition
)。 - 方法:
await()
(等待)、signal()
(唤醒单个)、signalAll()
(唤醒所有)。
- 作用:
三、原子操作类(无锁编程核心)
-
原子类(
AtomicXXX
)- 核心类:
AtomicInteger
(原子int)、AtomicLong
(原子long)、AtomicReference
(原子对象引用)、AtomicStampedReference
(解决ABA问题)。 - 作用:基于CAS实现无锁的原子操作,避免锁竞争开销。
- 场景:计数器(如接口调用次数)、并发环境下的对象引用更新。
- 核心类:
-
Unsafe
- 作用:提供底层CAS操作、内存管理等native方法,是原子类、AQS的实现基础。
- 注意:不建议直接使用(API不稳定,且可能破坏JVM内存模型)。
四、线程池与任务调度(并发任务管理)
-
ThreadPoolExecutor
- 作用:线程池核心实现,通过7个参数(核心线程数、最大线程数等)控制线程生命周期和任务调度。
- 场景:所有需要并发执行任务的场景(如接口异步处理、批量任务)。
-
Executors
- 作用:线程池工具类,提供快捷创建线程池的方法(如
newFixedThreadPool
、newCachedThreadPool
),但不推荐生产使用(可能导致OOM)。
- 作用:线程池工具类,提供快捷创建线程池的方法(如
-
Executor
/ExecutorService
- 作用:线程池顶层接口,
Executor
定义execute(Runnable)
,ExecutorService
扩展了生命周期管理(shutdown()
、submit()
等)。
- 作用:线程池顶层接口,
-
Callable
/Future
/FutureTask
- 作用:
Callable
是带返回值的任务接口,Future
用于获取异步任务结果,FutureTask
是Future
的实现类(常用作线程池提交任务的载体)。 - 场景:需要获取任务执行结果的异步场景(如并行计算)。
- 作用:
-
ScheduledExecutorService
- 作用:支持定时/周期性任务的线程池(如
scheduleAtFixedRate
),替代Timer
(线程安全且功能更全)。
- 作用:支持定时/周期性任务的线程池(如
五、同步工具类(多线程协作)
-
CountDownLatch
- 作用:倒计时器,让主线程等待多个子线程完成后再执行(
countDown()
减计数,await()
等待计数为0)。 - 场景:测试用例等待多线程准备就绪、汇总多任务结果。
- 作用:倒计时器,让主线程等待多个子线程完成后再执行(
-
CyclicBarrier
- 作用:循环栅栏,让多个线程到达屏障点后再一起继续执行(可重复使用)。
- 区别于
CountDownLatch
:CyclicBarrier
是线程间互相等待,且可重置计数。 - 场景:分阶段任务(如数据处理的“读取→清洗→分析”三阶段,所有线程完成读取后再进入清洗)。
-
Semaphore
- 作用:信号量,通过“许可”控制并发访问资源的线程数(
acquire()
获取许可,release()
释放)。 - 场景:限流(如控制并发请求数)、资源池(如数据库连接池)。
- 作用:信号量,通过“许可”控制并发访问资源的线程数(
-
Exchanger
- 作用:让两个线程在指定点交换数据(如生产者和消费者交换缓冲区)。
- 场景:数据交换(如校验任务:线程A生成数据,线程B校验,交换后对比结果)。
六、并发容器(线程安全的数据结构)
-
ConcurrentHashMap
- 作用:线程安全的HashMap,JDK 8后通过CAS+synchronized实现(摒弃分段锁),支持高并发读写。
- 场景:缓存、共享配置存储。
-
CopyOnWriteArrayList
/CopyOnWriteArraySet
- 作用:写入时复制的容器,读操作无锁,写操作复制新数组替换旧数组,适合读多写少场景。
- 场景:配置列表、日志列表(极少修改,频繁查询)。
-
BlockingQueue
及实现类- 核心类:
ArrayBlockingQueue
(有界数组队列)、LinkedBlockingQueue
(链表队列)、SynchronousQueue
(无缓冲队列)、PriorityBlockingQueue
(优先级队列)。 - 作用:支持阻塞的
put()
(满时阻塞)和take()
(空时阻塞),是生产者-消费者模型的核心。 - 场景:任务队列(线程池用它存储任务)、消息传递。
- 核心类:
-
ConcurrentLinkedQueue
- 作用:无锁的并发队列(基于CAS),性能优于
BlockingQueue
,但不支持阻塞操作。 - 场景:高并发非阻塞的队列场景(如日志收集)。
- 作用:无锁的并发队列(基于CAS),性能优于
七、线程管理与协作
-
ThreadLocal
- 作用:线程本地存储,每个线程有独立变量副本,避免线程安全问题(如存储用户上下文、事务信息)。
- 注意:必须
remove()
,否则线程池复用会导致内存泄漏。
-
ThreadFactory
- 作用:自定义线程创建(如设置线程名、优先级、是否为守护线程),便于问题排查。
-
Fork/Join
框架- 核心类:
ForkJoinPool
(分治线程池)、RecursiveTask
(带返回值的分治任务)、RecursiveAction
(无返回值的分治任务)。 - 作用:基于“分治思想”并行处理大数据量任务(如大数组求和、文件搜索)。
- 核心类:
八、锁优化与高级工具
-
ReentrantReadWriteLock
- 作用:读写锁,允许多个读线程并发访问,写线程独占,适合读多写少场景(如缓存)。
-
StampedLock
- 作用:JDK 8新增的乐观读锁,性能优于
ReentrantReadWriteLock
,支持“乐观读→悲观读→写锁”的转换。
- 作用:JDK 8新增的乐观读锁,性能优于
-
Phaser
- 作用:灵活的阶段同步工具,结合了
CountDownLatch
和CyclicBarrier
的功能,支持动态增减参与线程。
- 作用:灵活的阶段同步工具,结合了
这些概念是Java并发编程的核心,实际开发中需结合场景灵活组合使用(如线程池+ConcurrentHashMap
+CountDownLatch
处理高并发任务),同时注意线程安全、资源释放(如ThreadLocal.remove()
、锁释放)等细节。