Java JUC高级学习系列之三:原子变量与 CAS 算法

一、原子变量

在Java并发编程实战中线程安全的定义是这样的:当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替运行,并且不需要额外的同步及在调用该代码不必做其它的协调,这个类的行为仍然是正确的,那么这个类就是线程安全的。由这定义我们可以知道,显然只有资源竞争时才会导致线程不安全,因此无状态对象永远是线程安全的。

原子操作的描述:多个线程执行一个操作时,其中任何一个线程要么完全执行完此操作,要么没有执行此操作的任何步骤,那么这个操作就是原子的。也就是原子类操作是不能被线程调度机制中断的操作。

原子变量类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将 volatile 值、字段和数组元素的概念扩展到那些也提供原子条件更新操作的类。

 类 AtomicBoolean、 AtomicInteger、 AtomicLong 和 AtomicReference 的实例各自提供对相应类型单个变量的访问和更新。每个类也为该类型提供适当的实用工具方法。

AtomicIntegerArray、 AtomicLongArray 和 AtomicReferenceArray 类进一步扩展了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方面也引人注目,这对于普通数组来说是不受支持的。

核心方法: boolean compareAndSet(expectedValue, updateValue)

 java.util.concurrent.atomic 包下提供了一些原子操作的常用类:

 AtomicBoolean 、 AtomicInteger 、 AtomicLong 、 AtomicReference

 AtomicIntegerArray 、 AtomicLongArray

 AtomicMarkableReference

 AtomicReferenceArray

 AtomicStampedReference

案例解析:

改进方案:

二、CAS算法:

CAS (Compare-And-Swap) 是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问。

 CAS 是一种无锁的非阻塞算法的实现。

 CAS 包含了 3 个操作数:

 需要读写的内存值 V

 进行比较的值 A

 拟写入的新值 B

 当且仅当 V 的值等于 A 时, CAS 通过原子方式用新值 B 来更新 V 的值,否则不会执行任何操作

// 模拟CAS 算法

classCompareAndSwap{

privateintvalue;

// 获取内存值

publicsynchronizedintget(){

returnvalue;

}

// 无论更新成功与否,都返回修改之前的内存值

publicsynchronizedintcompareAndSwap(intexpectedValue,intnewValue){

// 获取旧值

intoldValue =value;

if(oldValue == expectedValue){

this.value= newValue;

}

// 返回修改之前的值

returnoldValue;

}

// 判断是否设置成功

publicsynchronized booleancompareAndSet(intexpectedValue,intnewValue){

returnexpectedValue == compareAndSwap(expectedValue, newValue);

}

}

publicclassTestCompareAndSwap{

publicstaticvoidmain(String[] args){

final CopareAndSwap cas =newCompareAndSwap();

for(inti=; i

// 创建10个线程,模拟多线程环境

newThead(newRunnable(){

publicvoidrun(){

intexpectedValue = cas.get();

boolean b = cas.compareAndSet(expectedValue, (int)(Math.random()*100));

System.out.println(b); } }).start(); } }}

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180118G069QQ00?refer=cp_1026

扫码关注云+社区