一览 JDK 并发包(J.U.C)

2020-09-09  

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