Java提高——JUC线程原子变量和CAS算法
原子变量
- 类的小工具包,支持在单个变量上解除锁的线程安全编程。事实上,此包中的类可将volatile值,字段和数组元素的概念扩展到那些提供原子条件更新操作的类。
- 类AtomicBoolean、AtomicInteger、AtomicLong和AtomicReference的实例各自提供对相应类型单个变量的访问和更新。每个类也为该类型提供适当的实用工具方法。
- AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray类进一步展示了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供volatile访问语义方面也引人注目,这对于普通数组来说是不受支持的。
- 核心方法:boolean compareAndSet(expectedValue,updateValue)
- java.util.concurrent.atomic包下提供了一些原子操作的常用类。
class Atomic implements Runnable{ private int serialNum = 0; public int getSerialNum() { return serialNum++; } public void setSerialNum(int serialNum) { this.serialNum = serialNum; } @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" "+getSerialNum()); } } public class TestAtomic { public static void main(String[] args) { Atomic a = new Atomic(); for (int i = 0; i < 10; i++) { new Thread(a).start(); } } }
不能确保原子性:
CAS算法
- CAS(Compare-And-Swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器的一种特殊指令,用于管理对共享数据的并发访问。
- CAS是一种无锁的非阻塞算法的实现
- CAS包含了3个操作数:
需要读写的内存值V
进行比较的值A
拟写入的新值B - 当且仅当V的值等于A时,CAS通过原子方式用新值B更新V的值,否则不会执行任何操作。
/** * @author chenpeng * @date 2018/7/10 16:56 * * 一、i++ 的原子性问题:i++的实际操作分为三个步骤:读-写-改 * int i = 10 * i++; * 底层:int temp = i; * i = i+1; * temp = i; * 二、原子变量:jdk1.5之后 java.util.current.atomic包下提供了常用的原子变量 * 1、这些变量都是有volatile修饰的,保证了内存可见性问题 * 2、CAS(Compare-And-Swap)算法保证数据的原子性。 * CAS算法是硬件对于并发操作共享数据的支持 * CAS包含了3个操作数: * 需要读写的内存值V * 进行比较的值A * 拟写入的新值B * 当且仅当A==V时,才会将V=B更新,否则不做任何操作 */ class Atomic implements Runnable{ //private int serialNum = 0; private AtomicInteger serialNum = new AtomicInteger(); public int getSerialNum() { return serialNum.incrementAndGet(); } @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" "+getSerialNum()); } } public class TestAtomic { public static void main(String[] args) { Atomic a = new Atomic(); for (int i = 0; i < 10; i++) { new Thread(a).start(); } } }
模拟实现CAS
public class ImplementCAS { public static void main(String[] args) { final CAS cas = new CAS(); for (int i = 0; i < 10; i++) { new Thread(new Runnable() { @Override public void run() { int expectedValue = cas.getValue(); boolean b = cas.compareAndSet(expectedValue,(int) Math.random()*101); System.out.println(b); } }).start(); } } } class CAS{ private int value; //获取内存值 public synchronized int getValue(){ return value; } //比较 public synchronized int compareAndSwap(int expectedValue,int newValue){ int oldValue = value; if (oldValue==expectedValue){ this.value = newValue; } return oldValue; } //设置 public synchronized boolean compareAndSet(int expectedValue,int newValue){ return expectedValue == compareAndSwap(expectedValue,newValue); } }