java多线程归类
在 Java 的 JUC(java.util.concurrent) 包中,包含了许多工具类和框架,用于简化多线程编程,解决常见的并发问题。这些工具可以根据功能归类如下:
1. 锁(Locks)
JUC 提供了灵活的锁机制,用于控制线程之间的同步。
| 工具类 | 描述 |
|---|---|
ReentrantLock |
可重入锁,支持公平锁和非公平锁,提供更灵活的锁机制(如可中断、超时等)替代 synchronized。 |
ReentrantReadWriteLock |
读写锁,允许多个线程同时读取,但写线程独占,适用于读多写少的场景。 |
StampedLock |
改进版的读写锁,支持乐观读锁,性能通常比 ReentrantReadWriteLock 更高。 |
LockSupport |
低级线程阻塞和唤醒工具,常用于实现自定义同步工具。 |
2. 线程同步工具(Synchronization Tools)
这些工具类用于在线程间协调同步、通信等操作。
| 工具类 | 描述 |
|---|---|
CountDownLatch |
倒计时锁存器,允许一个或多个线程等待其他线程完成操作后再继续执行。 |
CyclicBarrier |
循环栅栏,允许一组线程互相等待,直到所有线程都到达屏障后再继续执行。 |
Semaphore |
信号量,用于限制同时访问某资源的线程数量。 |
Exchanger |
两个线程之间交换数据的同步点。 |
Phaser |
可替代 CyclicBarrier 和 CountDownLatch,支持更复杂的多阶段任务协调。 |
3. 并发集合(Concurrent Collections)
线程安全的集合类,提供高效的并发访问,适合多线程环境。
| 工具类 | 描述 |
|---|---|
ConcurrentHashMap |
高效的线程安全哈希表,替代 Hashtable,支持并发读写操作。 |
ConcurrentSkipListMap |
支持排序的线程安全 Map,基于跳表实现。 |
ConcurrentSkipListSet |
支持排序的线程安全 Set,基于跳表实现。 |
CopyOnWriteArrayList |
线程安全的 ArrayList,适合读多写少的场景。 |
CopyOnWriteArraySet |
线程安全的 Set,基于 CopyOnWriteArrayList 实现。 |
LinkedBlockingQueue |
基于链表的阻塞队列,支持生产者-消费者模型。 |
ArrayBlockingQueue |
基于数组的阻塞队列,队列容量是固定的。 |
PriorityBlockingQueue |
支持优先级的阻塞队列。 |
DelayQueue |
支持延迟获取元素的阻塞队列。 |
SynchronousQueue |
一个没有容量的阻塞队列,每次插入操作必须等待一个移除操作。 |
LinkedTransferQueue |
高性能的阻塞队列,支持生产者直接将数据传递给消费者。 |
ConcurrentLinkedQueue |
高效的无界非阻塞队列,基于链表实现。 |
ConcurrentLinkedDeque |
高效的双端无界非阻塞队列。 |
4. 原子类(Atomic Classes)
提供线程安全的原子操作,支持基本类型和引用类型。
| 工具类 | 描述 |
|---|---|
AtomicInteger |
针对 int 类型的原子操作。 |
AtomicLong |
针对 long 类型的原子操作。 |
AtomicBoolean |
针对 boolean 类型的原子操作。 |
AtomicReference<T> |
针对引用类型的原子操作。 |
AtomicStampedReference<T> |
与 AtomicReference 类似,增加了版本号(用于解决 ABA 问题)。 |
AtomicMarkableReference<T> |
与 AtomicReference 类似,增加了标记位(用于记录额外状态)。 |
LongAdder |
高效的计数器,适用于高并发场景,比 AtomicLong 性能更高(使用分段累加)。 |
DoubleAdder |
针对 double 类型的高效计数器,类似 LongAdder。 |
LongAccumulator |
高效的累加器,支持自定义二元操作(如加法、乘法)。 |
DoubleAccumulator |
针对 double 类型的累加器,支持自定义二元操作。 |
5. 线程池和任务调度
JUC 提供了线程池和任务调度工具,用于管理线程的生命周期和任务执行。
| 工具类 | 描述 |
|---|---|
Executor |
执行任务的顶层接口,定义了任务的执行方式。 |
ExecutorService |
扩展了 Executor,提供管理线程池的方法(如关闭线程池)。 |
ThreadPoolExecutor |
自定义线程池的实现类,允许控制核心线程数、最大线程数、队列类型等。 |
ScheduledExecutorService |
支持定时任务和周期性任务执行的线程池。 |
ForkJoinPool |
用于分治任务(Fork/Join 模型)的线程池,适合大规模并行计算。 |
Executors |
工厂类,用于快速创建常见类型的线程池(如固定线程池、缓存线程池、单线程池)。 |
6. 并发工具类(其他)
一些通用的工具类,用于辅助多线程开发。
| 工具类 | 描述 |
|---|---|
Future |
表示异步任务的结果,可以通过 get() 方法获取任务结果或阻塞等待任务完成。 |
CompletableFuture |
支持异步编程的工具,提供丰富的异步方法链和回调机制。 |
FutureTask |
可将任务封装成 Future,支持异步任务的执行和取消。 |
CompletionService |
将任务提交和结果获取分离,结合线程池使用,适合处理批量任务。 |
7. 线程工具类
JUC 提供了一些工具用于线程管理和操作。
| 工具类 | 描述 |
|---|---|
ThreadLocal |
线程局部变量,每个线程都有独立的副本,适合存储线程独有的数据。 |
ThreadFactory |
用于创建线程的工厂类,允许自定义线程的创建逻辑(如设置线程名称、优先级)。 |
总结
JUC 工具根据功能可以大致分为以下几类:
- 锁(如
ReentrantLock、StampedLock)。 - 线程同步工具(如
CountDownLatch、Semaphore)。 - 并发集合(如
ConcurrentHashMap、CopyOnWriteArrayList)。 - 原子类(如
AtomicInteger、LongAdder)。 - 线程池和任务调度(如
ThreadPoolExecutor、ForkJoinPool)。 - 线程工具类(如
ThreadLocal、ThreadFactory)。 - 异步任务工具(如
Future、CompletableFuture)。
这些工具为开发者提供了强大的多线程编程能力,同时大大简化了并发问题的处理。
下面对 JUC 工具中常用的参数和 API 进行归类,帮助更好地理解和使用这些工具。
1. 锁(Locks)
1.1 ReentrantLock
常用参数:
fair:是否为公平锁(默认是非公平锁)。- 公平锁:线程按请求锁的顺序获取锁。
- 非公平锁:线程可能会"插队",性能更高。
常用 API:
lock():获取锁,如果锁已经被占用,则等待。tryLock():尝试获取锁,如果锁未被占用则立即返回true,否则返回false。tryLock(long timeout, TimeUnit unit):尝试在指定时间内获取锁,超时返回false。lockInterruptibly():支持线程中断的方式获取锁。unlock():释放锁。isLocked():判断锁是否被占用。
1.2 ReentrantReadWriteLock
常用 API:
- 获取读锁:
readLock().lock():获取读锁。readLock().unlock():释放读锁。
- 获取写锁:
writeLock().lock():获取写锁。writeLock().unlock():释放写锁。
- 其他:
isWriteLocked():是否有线程持有写锁。getReadLockCount():当前读锁的持有线程数。
1.3 StampedLock
常用 API:
- 乐观读锁:
long stamp = tryOptimisticRead():尝试获取乐观读锁。validate(stamp):验证乐观读锁是否有效。
- 悲观读锁:
long stamp = readLock():获取悲观读锁。unlockRead(stamp):释放悲观读锁。
- 写锁:
long stamp = writeLock():获取写锁。unlockWrite(stamp):释放写锁。
2. 线程同步工具(Synchronization Tools)
2.1 CountDownLatch
常用参数:
count:初始计数值,表示需要等待的线程数量。
常用 API:
await():阻塞当前线程,直到计数器归零。countDown():将计数器减 1。getCount():获取当前计数器的值。
2.2 CyclicBarrier
常用参数:
parties:线程数量,所有线程到达屏障后才会继续执行。Runnable barrierAction(可选):所有线程到达屏障后,执行的任务。
常用 API:
await():让线程在屏障处等待,直到所有线程都到达。await(long timeout, TimeUnit unit):带超时时间的await。getParties():获取需要等待的线程总数。getNumberWaiting():获取当前正在等待的线程数量。
2.3 Semaphore
常用参数:
permits:许可的数量,表示最多允许多少线程同时访问资源。fair(可选):是否为公平信号量。
常用 API:
acquire():获取一个许可,若无可用许可则阻塞。tryAcquire():尝试获取一个许可,立即返回结果。release():释放一个许可。availablePermits():返回当前可用的许可数量。
2.4 Exchanger
常用 API:
exchange(V value):线程间交换数据,阻塞直到另一个线程也调用exchange。exchange(V value, long timeout, TimeUnit unit):带超时的交换方法。
3. 并发集合(Concurrent Collections)
3.1 ConcurrentHashMap
常用参数:
initialCapacity:初始容量。loadFactor:负载因子。concurrencyLevel:并发级别,默认是 CPU 核心数。
常用 API:
putIfAbsent(K key, V value):如果键不存在则插入。compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction):计算新值并替换。forEach(long parallelismThreshold, BiConsumer<? super K, ? super V> action):并行遍历。
3.2 CopyOnWriteArrayList
常用 API:
add(E e):添加元素。remove(Object o):删除元素。set(int index, E element):设置指定位置的元素。iterator():返回弱一致性的迭代器。
3.3 阻塞队列(以 LinkedBlockingQueue 为例)
常用 API:
put(E e):添加元素,若队列满则阻塞。take():获取并移除队头元素,若队列为空则阻塞。offer(E e):尝试添加元素,非阻塞。poll(long timeout, TimeUnit unit):尝试在超时时间内获取元素。
4. 原子类(Atomic Classes)
4.1 AtomicInteger
常用 API:
get():获取当前值。set(int newValue):设置新值。incrementAndGet():自增 1 并返回新值。addAndGet(int delta):增加指定值并返回结果。compareAndSet(int expect, int update):CAS 操作,原子更新值。
4.2 LongAdder
常用 API:
add(long x):增加指定值。sum():获取累加的总和。reset():重置计数器为 0。
5. 线程池和任务调度
5.1 ThreadPoolExecutor
常用参数:
corePoolSize:核心线程数。maximumPoolSize:最大线程数。keepAliveTime:非核心线程空闲存活时间。workQueue:任务队列,用于存放待执行任务。threadFactory:线程工厂,用于创建线程。handler:拒绝策略,当任务无法处理时的策略。
常用 API:
execute(Runnable command):执行任务。submit(Callable<T> task):提交任务,返回Future。shutdown():关闭线程池,等待已提交任务完成。shutdownNow():立即关闭线程池,尝试中断正在执行的任务。
5.2 ScheduledExecutorService
常用 API:
schedule(Runnable command, long delay, TimeUnit unit):延迟执行任务。scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit):固定频率执行任务。scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit):固定延迟执行任务。
6. 异步任务工具
6.1 CompletableFuture
常用 API:
supplyAsync(Supplier<U> supplier):异步执行任务,返回结果。thenApply(Function<? super T,? extends U> fn):对任务结果进行转换。thenAccept(Consumer<? super T> action):对任务结果执行消费操作。exceptionally(Function<Throwable,? extends T> fn):处理异常情况。join():阻塞并获取结果。
总结
以上是 JUC 工具中常用的参数和 API,按功能划分包括 锁、线程同步工具、并发集合、原子类、线程池和任务调度 以及 异步任务工具。这些工具为多线程编程带来了极大的便利,开发者可以根据具体需求灵活选择合适的工具。
搭配使用,提供了一种更灵活的线程通信方式,类似于传统的 wait() 和 notify() 方法,但功能更强大。
Condition 允许线程等待某些条件满足时再继续执行,同时支持精准的线程调度和多条件等待。
1. Condition 的主要 API 概述
| 方法 | 描述 |
|---|---|
void await() |
将当前线程放入等待队列,并释放锁,直到被其他线程 signal 或 signalAll 唤醒。 |
void awaitUninterruptibly() |
类似 await(),但不会响应中断。 |
long awaitNanos(long nanosTimeout) |
在指定时间内等待条件,超时返回剩余时间,或被唤醒。 |
boolean awaitUntil(Date deadline) |
等待条件,直到指定时间到期或被唤醒。 |
void signal() |
唤醒一个等待该条件的线程。 |
void signalAll() |
唤醒所有等待该条件的线程。 |
2. Condition 的使用步骤
-
获取锁对象
Condition是通过Lock(通常是ReentrantLock)创建的,因此需要先获取锁。 -
创建
Condition对象
使用Lock的newCondition()方法创建一个Condition对象。 -
线程等待和唤醒
- 调用
await()使线程进入等待状态。 - 调用
signal()或signalAll()唤醒等待线程。
- 调用
-
注意锁的使用
- 调用
await()或signal()之前,线程必须持有锁。 - 使用
finally块确保锁的释放。
- 调用
以下是 CountDownLatch 和 CyclicBarrier 的简洁对比,着重展示功能差异:
| 特性 | CountDownLatch |
CyclicBarrier |
|---|---|---|
| 主要功能 | 主线程等待其他线程完成任务后继续执行。 | 线程相互等待,直到所有线程都到达屏障后再继续执行。 |
| 是否可重用 | 不可重用,计数器只能减到 0 一次。 | 可重用,屏障点被所有线程通过后自动重置。 |
| 线程等待方式 | 主线程调用 await() 等待计数器减为 0。 |
所有线程调用 await() 等待其他线程到达屏障点。 |
| 回调支持 | 不支持回调。 | 支持,当所有线程到达屏障时,可执行指定回调任务。 |
| 适用场景 | 一次性任务分发与汇总,主线程等待子线程完成工作。 | 多线程任务的阶段性同步或分布式任务结果汇总。 |
总结:
- 用于主线程等待子线程的场景选择
CountDownLatch。 - 用于多线程相互等待、阶段性同步的场景选择
CyclicBarrier。
2. CountDownLatch 的核心方法
| 方法 | 描述 |
|---|---|
CountDownLatch(int count) |
构造方法,初始化计数器为指定值 count。 |
void await() |
阻塞当前线程,直到计数器减为 0。 |
boolean await(long timeout, TimeUnit unit) |
带超时的等待方法,超时会返回 false。 |
void countDown() |
将计数器减 1,唤醒等待线程(如果计数器减为 0)。 |
long getCount() |
返回当前计数器的值。 |
3. CyclicBarrier 的核心方法
| 方法 | 描述 |
|---|---|
CyclicBarrier(int parties) |
构造方法,初始化屏障点,指定需要等待的线程数。 |
CyclicBarrier(int parties, Runnable barrierAction) |
构造方法,带回调功能,当所有线程到达屏障时执行回调任务。 |
int await() |
当前线程到达屏障,进入等待状态,直到所有线程到达屏障点。返回当前线程到达屏障的顺序号。 |
int await(long timeout, TimeUnit unit) |
带超时的 await 方法,超时会抛出 TimeoutException。 |
int getParties() |
返回屏障点需要等待的线程数。 |
int getNumberWaiting() |
返回当前正在屏障点等待的线程数。 |
boolean isBroken() |
返回屏障是否被打破(如线程超时或被中断)。 |
void reset() |
重置屏障,唤醒所有等待线程,并将屏障恢复为初始状态。 |
4. 总结对比
| 工具 | 特点 |
|---|---|
CountDownLatch |
- 适合主线程等待多个子线程完成任务的场景。 |
| - 一次性工具,计数器不能重置。 | |
CyclicBarrier |
- 适合多线程需要在某个点同步后再继续执行的场景。 |
| - 可重复使用,屏障点被所有线程通过后会自动重置。 | |
| - 支持回调函数,适合阶段性结果汇总或特殊任务。 |
todo
补充下synchronized原理

浙公网安备 33010602011771号