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原理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!