JDK 并发包的知识不像设计模式,设计模式的知识点是易懂难精,而 JDK 并发包尤其是从源码角度去看,刚开始比较难理解,但理解之后就可以拿去使用也不易忘记。
通过这次整理并发包的结构,越发觉得从学习到掌握知识需要有个过程。两三年前看到并发包里的类(接口)名大多不知道它们是干嘛的,而现在基本能明白包中 80% 的类(接口)是用来解决什么问题的。
这里顺带分享一个经验,就是很多学习编程的同学,喜欢一上来就看源码。当初我也是这样,并发包里的源码我看过两遍,第一遍硬着头皮基本啥也没看懂。看不懂源码最主要的一个原因就是,我都没能理解工具类怎么用,怎么可能看懂 Doug Lea 为什么这么写?
学习源码的一般思路是,先熟练使用,再深入带着问题深入研究源码是如何实现功能的,由点及面,窥得整个源码的全貌。
学习 JDK 并发工具包,最好把数组、链表、队列这些数据结构理解透彻,不然这块源码会非常难看懂。
整理的 JDK 1.8 java.util.concurrent 包下大部分类和接口的作用,如下:
原子类
AtomicBoolean | 可原子更新的 Boolean |
AtomicInteger | 可原子更新的 Integer |
AtomicIntegerArray | 可原子更新元素的 int 数组 |
AtomicIntegerFieldUpdater | 基于反射可原子更新类中的 Integer 成员属性 |
AtomicLong | 可原子更新的 Long |
AtomicLongArray | 可原子更新元素的 int 数组 |
AtomicLongFieldUpdater | 基于反射可原子更新类中的 Long 成员属性 |
AtomicMarkableReference | 带 boolean 标记可原子更新对象,多了 boolean 类型的 mark,可解决 ABA 问题 |
AtomicReference | 可原子更新对象 |
AtomicReferenceArray | 可原子更新对象数组元素 |
AtomicReferenceFieldUpdater | 基于反射可原子更新类中的成员属性对象 |
AtomicStampedReference | 带有版本戳可原子更新对象,基于 int 版本戳,可以解决 ABA 问题 |
DoubleAccumulator | DoubleAdder 的增强版,支持定义计算函数 |
DoubleAdder | Double 累加器,中途 sum可能存在误差,保证结果最终一致,高并发下用 cell 数组把线程分组计算更新 |
LongAccumulator | LongAdder 的增强版,支持定义计算函数 |
LongAdder | Long 累加器,中途 sum 可能存在误差,保证结果最终一致,高并发下用 cell 数组把线程分组计算更新,高并发下性能比 AtomicLong 好,但空间复杂度高 |
Striped64 | LongAdder、LongAccumulator、DoubleAdder、DoubleAccumulator,通过 cell 数组把线程分组计算更新的底层实现 |
锁
Lock | 显式锁定义顶层接口 |
└ ReentrantLock | 可重入锁 |
ReadWriteLock | 读写锁接口 |
└ ReentrantReadWriteLock | 可重入读写锁 |
StampedLock | 解决读写锁的写饥饿问题,支持写锁、悲观读锁和乐观读,乐观读是无所得允许一个线程获取写锁 |
Condition | 通过 Lock.newCondition 获取,完成等待与唤醒 |
LockSupport | 线程阻塞工具类 |
AbstractOwnableSynchronizer | 设置和获取独占锁的拥有者线程,供子类使用 |
└ AbstractQueuedSynchronizer | 大名鼎鼎的 AQS,自定义同步器框架,ReentrantLock、ReentrantReadWriteLock 等都是基于此实现 |
└ AbstractQueuedLongSynchronizer | AQS 的子类,state 为 long,支持 64 位,其他与 AQS 无区别 |
线程池
Executor | 线程池顶层接口,提交可运行任务 |
└ ExecutorService | 提供停止线程池、提交带结果的任务等方法的线程池接口 |
└ AbstractExecutorService | ExecutorService 的默认实现 |
└ ForkJoinPool | 支持任务窃取与拆分的线程池 |
└ ThreadPoolExecutor | 线程池的实现类,可通过构造方法与不公参数创建自己想要的线程池 |
└ ScheduledExecutorService | 可延迟或周期执行任务的线程池接口 |
└ ScheduledThreadPoolExecutor | 可延迟或周期执行任务的线程池,也是 ThreadPoolExecutor 的子类 |
Executors | 各种线程池的创建、任务类型的转换等功能的工具类 |
Callable | 带返回结果的任务的接口 |
Future | 表示异步计算结果的接口,检查计算是否完成,等待计算完成,等待获取结果 |
└ ForkJoinTask | ForkJoinPool 的任务,比线程更轻量 |
└ CountedCompleter | 在触发完成动作时,检查有没有挂起动作,若没有则执行一个完成动作 |
└ RecursiveAction | 在 ForkJoinPool 任务拆分递归中,无结果的 ForkJoinTask,始终返回 null |
└ RecursiveTask | 在 ForkJoinPool 任务拆分递归中,有结果的 ForkJoinTask |
└ RunnableFuture | Runnable、Future 的子接口 |
└ FutureTask | 一种可取消的异步计算任务,同时支持阻塞获取任务结果 |
└ ScheduledFuture | 可延迟、取消的 Future 的接口 |
└ RunnableScheduledFuture | RunnableFuture、ScheduledFuture 的子接口 |
CompletionService | 异步任务执行完成有序化接口 |
└ ExecutorCompletionService | CompletionService 的实现,线程池 Executor 和阻塞队列 BlockingQueue 的功能融合,让异步任务有序化,先执行完成的先进入阻塞队列 |
CompletionStage | 接口定义了线程完成阶段可以采用的不同执行方式,如异步,合并等 |
└ CompletableFuture | 计算完成,可设置值与状态、支持触发依赖函数和依赖操作,也是 Future 的子类 |
RejectedExecutionHandler | 线程池拒绝策略接口 |
└ AbortPolicy | 拒绝任务,抛出异常策略 |
└ CallerRunsPolicy | 提交任务的线程直接运行拒绝的任务的策略 |
└ DiscardOldestPolicy | 丢弃最早的任务,提交新任务策略 |
└ DiscardPolicy | 直接丢掉被拒绝的任务 |
ThreadFactory | 线程工厂接口,用于线程池创建线程 |
ForkJoinWorkerThread | 被 ForkJoinPool 管理,执行 ForkJoinTask 任务的线程 |
TimeUnit | 时间单位枚举 |
Delayed | 标记 delay 的接口 |
可并发的数据结构
Collection | 集合接口 |
└ Queue | 队列接口 |
└ ConcurrentLinkedQueue | 基于单向链表实现的并发队列 |
└ BlockingQueue | 阻塞队列接口 |
└ ArrayBlockingQueue | 基于数组实现的阻塞队列,支持有界 |
└ LinkedBlockingQueue | 基于单向链表实现的阻塞队列,支持有界 |
└ DelayQueue | 无界阻塞延迟队列 |
└ PriorityBlockingQueue | 支持优先级的无界阻塞队列 |
└ SynchronousQueue | 直接将元素交给等待中的消费者,无等待的消费者,插入元素阻塞,无容量 |
└ TransferQueue | BlockingQueue 和 SynchronousQueue 的整合,可以在队列阻塞,也可以阻塞在等待消费者 |
└ LinkedTransferQueue | ConcurrentLinkedQueue、SynchronousQueue(公平模式)和LinkedBlockingQueue 的 超集,性能更高 |
└ Deque | 双端队列接口 |
└ BlockingDeque | 阻塞双端队列接口 |
└ ConcurrentLinkedDeque | 基于双向链表的无界并发双端队列 |
└ List | 有序集合接口 |
└ CopyOnWriteArrayList | 基于数组写入时可并发有序集合 |
└ Set | 元素不重复集合接口 |
└ CopyOnWriteArraySet | 基于数组写入时可并发元素不重复集合 |
└ ConcurrentSkipListSet | 基于 ConcurrentSkipListMap 实现的可并发元素不重复集合 |
Map | 键值对集合接口 |
└ ConcurrentMap | 可并发的键值对集合接口 |
└ ConcurrentHashMap | 基于 hash 与分段锁,可并发的键值对集合 |
└ ConcurrentNavigableMap | 可搜索导航的并发键值对集合接口 |
└ ConcurrentSkipListMap | 基于跳表实现的可搜索导航的并发键值对集合 |
工具
Semaphore | 信号量,与锁最大的不同在于,允许多个线程访问一个临界区 |
CyclicBarrier | 循环栅栏,可循环利用的屏障,允许一组线程全部等待对方到达一个公共屏障点再一起执行 |
CountDownLatch | 一个或多个线程等待其他线程的操作完成 |
Exchanger | 两个工作线程在交换点交换数据的工具类 |
ThreadLocalRandom | 本地线程的生成随机数工具类 |
Phaser | 可重用的同步屏障,比 CyclicBarrier、CountDownLatch 灵活 |
异常
TimeoutException | 阻塞操作超时异常 |
CompletionException | 完成结果或任务过程引发的异常 |
BrokenBarrierException | 线程试图等待处于中断状态的屏障 或 线程等待时进入中断状态,抛出的异常 |
CancellationException | 获取值的任务被 cancel 异常 |
ExecutionException | 获取任务结果,引发异常,导致中止 |
ConstXiong 备案号:苏ICP备16009629号-3