写点什么

Java Core「4」java.util.concurrent 包简介

作者:Samson
  • 2022 年 5 月 24 日
  • 本文字数:1680 字

    阅读完需:约 6 分钟

Java Core「4」java.util.concurrent 包简介

01-原子类

java.util.concurrent 包中提供了如下几类原子操作类:


  • AtomicBoolean / AtomicInteger / AtomicLong:底层通过 CAS + volatile 实现线程安全的修改、查询操作。缺点是:

  • 可能存在 ABA 问题

  • 仅能实现对单个变量操作的原子性,多个原子类变量的复核操作,需要其他的机制保证线程安全,例如锁。

  • AtomicReference / AtomicStampedReference / AtomicMarkableReference:提供对引用类型变量的原子操作。

  • AtomicStampedReference底层通过Pair存储引用和整型的 stamp,可以解决 ABA 问题

  • AtomicMarkableReference底层通过Pair存储引用和布尔型的 stamp,可以解决 ABA 问题

  • AtomicIntegerArray / AtomicLongArray / AtomicReferenceArray:提供对数组类型的原子访问

  • AtomicIntegerFieldUpdater / AtomicLongFieldUpdater / AtomicReferenceFieldUpdater:用来对对象中的 volatile 域进行原子更新。


原子类底层 CAS 操作是通过sun.misc.Unsafe类实现。关于此类更详细的介绍,参考美团技术团队的文章[1]。


[1] Java魔法类:Unsafe应用解析

02-线程安全容器

除了上节中提到的原子类,java.util.concurrent 包中还提供了几种容器的并发版本实现:


  • ConcurrentHashMap:HashMap 的并发版本,相比与线程安全的 HashTable 有更好的并发性能。JDK 1.7 与 JDK 1.8 中,该容器的实现略有差别。在 JDK 1.7 中,基于分段锁实现;在 JDK 1.8 中,基于数组+链表+红黑树+CAS 实现。

  • ConcurrentLinkedQueue / ConcurrentLinkedDeque:基于单向/双向链表的无界并发队列

  • ConcurrentSkipListMap / ConcurrentSkipListSet:TreeMap / TreeSet 的并发实现版本

  • CopyOnWriteArrayList / CopyOnWriteArraySet

03-Executor 框架、线程池和阻塞队列

java.util.concurrent 包中的一个非常重要的内容就是提供了 Executor 框架,主要目的是解耦任务本身和任务执行


Executor 框架的主要类包括:


  • Executor

  • ExecutorService / AbstractExecutorService:Executor 接口的增强,增加对自身生命周期的管理和异步执行方式的支持。

  • ScheduledExecutorService:周期性任务,在指定延时、或以指定频率执行任务。


线程池是对 ExecutorService 的实现:


  • ThreadPoolExecutor

  • ScheduledThreadPoolExecutor

  • ForkJoinPool,基于 Fork/Join 框架的线程池。


java.util.concurrent.Executors是一个工具类,提供了多个接口创建线程池。不过,阿里开发手册中不建议使用这个类创建线程池,主要原因时可能会使开发者忽略掉线程池的具体细节,而导致 OOM 或者 CPU 资源耗尽等场景。


与线程池相关联的数据结构是阻塞队列:


  • ArrayBlockingQueue / LinkedBlockingDeque / LinkedBlockingQueue:基于数组、链表的队列、双端队列;前者有界,后两者无界。

  • SynchronousQueue:不存储元素,容量为零,生产者对其插入数据必须阻塞等待消费者将其消费。

  • LinkedTransferQueue:是一个无界队列,生产者放入数据时不会阻塞,消费者如果取不到数据会被阻塞,引用范围比 SynchronousQueue 更广。

  • PriorityBlockingQueue:带优先级的阻塞队列。

  • DelayQueue:无界阻塞队列,其中的对象只能在其到期时才能从队列中取走。

04-同步工具类

java.util.concurrent 包中还提供了用于线程间同步的工具类,例如锁、信号量等。


  • ReentrantLock:可重入锁,支持公平、非公平模式。

  • ReentrantReadWriteLock:可重入读写锁,读-读并发,读-写、写-写互斥

  • StampedLock:与读写锁相比,允许读-写并发,通过乐观锁避免不一致。

  • LockSupport:工具类,提供 park / unpark 同步机制


除了上述锁实现,还有信号量机制:


  • Semaphore:信号量,与 Lock 不同,可以控制多个线程同时访问临界资源。

  • CountDownLatch:可以使一个线程(await),在等待其他线程完成各自的操作后(countDown),再继续执行。CountDownLatch 不可以重复使用。

  • CyclicBarrier:当所有线程都到达栅栏时,再继续执行。CyclicBarrier 是可以重复利用的。


除了上述两种外,还提供了 Exchanger,用于进行线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。


历史文章

Java Core「3」volatile 关键字

Java Core「2」synchronized 关键字

Java Core「1」JUC- 线程基础

发布于: 刚刚阅读数: 4
用户头像

Samson

关注

还未添加个人签名 2019.07.22 加入

还未添加个人简介

评论

发布
暂无评论
Java Core「4」java.util.concurrent 包简介_学习笔记_Samson_InfoQ写作社区