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 问题
DoubleAccumulatorDoubleAdder 的增强版,支持定义计算函数
DoubleAdderDouble 累加器,中途 sum可能存在误差,保证结果最终一致,高并发下用 cell 数组把线程分组计算更新
LongAccumulatorLongAdder 的增强版,支持定义计算函数
LongAdderLong 累加器,中途 sum 可能存在误差,保证结果最终一致,高并发下用 cell 数组把线程分组计算更新,高并发下性能比 AtomicLong 好,但空间复杂度高
Striped64LongAdder、LongAccumulator、DoubleAdder、DoubleAccumulator,通过 cell 数组把线程分组计算更新的底层实现



Lock显式锁定义顶层接口
└ ReentrantLock可重入锁
ReadWriteLock读写锁接口
└ ReentrantReadWriteLock可重入读写锁
StampedLock解决读写锁的写饥饿问题,支持写锁、悲观读锁和乐观读,乐观读是无所得允许一个线程获取写锁
Condition通过 Lock.newCondition 获取,完成等待与唤醒
LockSupport线程阻塞工具类
AbstractOwnableSynchronizer设置和获取独占锁的拥有者线程,供子类使用
└ AbstractQueuedSynchronizer大名鼎鼎的 AQS,自定义同步器框架,ReentrantLock、ReentrantReadWriteLock 等都是基于此实现
└ AbstractQueuedLongSynchronizerAQS 的子类,state 为 long,支持 64 位,其他与 AQS 无区别



线程池

Executor线程池顶层接口,提交可运行任务
└  ExecutorService提供停止线程池、提交带结果的任务等方法的线程池接口
    └ AbstractExecutorServiceExecutorService 的默认实现
      └ ForkJoinPool支持任务窃取与拆分的线程池
      └ ThreadPoolExecutor线程池的实现类,可通过构造方法与不公参数创建自己想要的线程池
    └ ScheduledExecutorService可延迟或周期执行任务的线程池接口
       └ ScheduledThreadPoolExecutor可延迟或周期执行任务的线程池,也是 ThreadPoolExecutor 的子类
Executors各种线程池的创建、任务类型的转换等功能的工具类
Callable带返回结果的任务的接口
Future表示异步计算结果的接口,检查计算是否完成,等待计算完成,等待获取结果
└  ForkJoinTaskForkJoinPool 的任务,比线程更轻量
    └ CountedCompleter在触发完成动作时,检查有没有挂起动作,若没有则执行一个完成动作
    └ RecursiveAction在 ForkJoinPool 任务拆分递归中,无结果的 ForkJoinTask,始终返回 null
    └ RecursiveTask在 ForkJoinPool 任务拆分递归中,有结果的 ForkJoinTask
└  RunnableFutureRunnable、Future 的子接口
    └ FutureTask一种可取消的异步计算任务,同时支持阻塞获取任务结果
└  ScheduledFuture可延迟、取消的 Future 的接口
    └ RunnableScheduledFutureRunnableFuture、ScheduledFuture 的子接口
CompletionService异步任务执行完成有序化接口
└  ExecutorCompletionServiceCompletionService 的实现,线程池 Executor 和阻塞队列 BlockingQueue 的功能融合,让异步任务有序化,先执行完成的先进入阻塞队列
CompletionStage接口定义了线程完成阶段可以采用的不同执行方式,如异步,合并等
└  CompletableFuture计算完成,可设置值与状态、支持触发依赖函数和操作,也是 Future 的zi
RejectedExecutionHandler线程池拒绝策略接口
└  AbortPolicy拒绝任务,抛出异常策略
└  CallerRunsPolicy提交任务的线程直接运行拒绝的任务的策略
└  DiscardOldestPolicy丢弃最早的任务,提交新任务策略
└  DiscardPolicy直接丢掉被拒绝的任务
ThreadFactory线程工厂接口,用于线程池创建线程
ForkJoinWorkerThread被 ForkJoinPool 管理,执行 ForkJoinTask 任务的线程
TimeUnit时间单位枚举
Delayed标记 delay 的接口



可并发的数据结构

Collection集合接口
└ Queue队列接口
    └ ConcurrentLinkedQueue基于单向链表实现的并发队列
    └ BlockingQueue阻塞队列接口
         ArrayBlockingQueue基于数组实现的阻塞队列,支持有界
        └ LinkedBlockingQueue基于单向链表实现的阻塞队列,支持有界
        └ DelayQueue***阻塞延迟队列
        └ PriorityBlockingQueue支持优先级的***阻塞队列
        └ SynchronousQueue直接将元素交给等待中的消费者,无等待的消费者,插入元素阻塞,无容量
         TransferQueueBlockingQueue 和 SynchronousQueue 的整合,可以在队列阻塞,也可以阻塞在等待消费者
           └ LinkedTransferQueueConcurrentLinkedQueue、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获取任务结果,引发异常而中止


更多相关文章

  1. 多线程基础必要知识点!看了学习多线程事半功倍
  2. 多线程三分钟就可以入个门了!
  3. 记一次应用线程被阻塞的问题排查
  4. 异步获取线程计算的结果-Future
  5. Redis为什么又引入了多线程?作者也逃不过“真香定理”?
  6. 详解第三种创建线程的方式-Callable接口
  7. java线程相关面试题(第一版)
  8. Java线程之线程的调度-让步

随机推荐

  1. android 颜色值 xml
  2. Android Property System
  3. 【Android UI】色板
  4. AndroidщАЪш┐ЗViewPagerхоЮчО
  5. 在eclipse中查看Android(安卓)SDK源代码
  6. 2013.10.14 “?android ”
  7. 默认的Android(安卓)Dialog 样式
  8. Android仿计算器布局代码
  9. Android SdCard写入权限
  10. jQ.Mobi源代码