Java基础12——并发工具

80 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Atomic类

简述常见的Atomic类

在很多时候,我们需要的仅仅是一个简单的、高效的、线程安全的++或者--方案,使用synchronized关键字和lock固然可以实现,但代价比较大,此时用原子类效率更高。

(1)基本数据类型的原子类有:

AtomicInteger 原子更新整形、AtomicLong 原子更新长整型、AtomicBoolean 原子更新布尔类型

(2)Atomic数组类型有:

AtomicIntegerArrayAtomicLongArray AtomicReferenceArray 原子更新数组里的元素。

(3)Atomic引用类型

AtomicReference 原子更新引用类型

AtomicMarkableReference 原子更新带有标记位的引用类型,可以绑定一个 boolean 标记

AtomicStampedReference 原子更新带有版本号的引用类型

Atomic类基本实现原理

以AtomicIntger 为例:

getAndIncrement()方法:以原子方式将当前的值加1,具体实现为:

  1. for 死循环中取得 AtomicInteger 里存储的数值
  2. 对 AtomicInteger 当前的值加 1
  3. 调用 compareAndSet 方法进行原子更新
  4. 先检查当前数值是否等于 expect
  5. 如果等于则说明当前值没有被其他线程修改,则将值更新为 next
  6. 如果不等于则更新失败返回 false,程序会进入 for 循环重新进行 compareAndSet 操作

CAS

Compare And Swap,是CPU为了解决并发问题而提供的指令;

该指令包含三个参数: 1.共享变量的内存地址A; 2.用于比较的值B; 3.共享变量的新值C;

当且仅当地址A处的值等于B时,才将地址A处的值更新为C;

自旋

使用CAS解决并发问题,通常要采用自旋操作;

所谓自旋就是循环尝试,即本次操作不成功则自动进入下-轮尝试;

ABA

判断相等不代表该值未被更新过(A->B->A) ;

若为基本类型可以忽视该问题,若为引用对象则需要进行检查;

ReadWriteLock

场景:适合读多写少的场景;

原则:1.允许多个线程同时读共享变量;

2.只允许一个线程写共享变量;

3.如果一个线程正在执行写操作,此时禁止其他线程读共享变量;

实现:ReentrantReadWriteLock,是读写锁,也是可重入锁,并且可以是公平的/非公平的;

CopyOnWrite

CopyOnWriteArrayList, CopyOnWriteArraySet;

修改时,容器会复制出一个新数组,在新数组上完成修改后再替换掉旧数组;