运用场合:并发场景,实现不能被打断的交换操作
主要思路:
public class TwoThreadsCompetition implements Runnable{ private volatile int value; public synchronized int compareAndSwap(int expectedValue, int newValue) { int oldValue = value; if (oldValue == expectedValue) { value = newValue; } return oldValue; } @Override public void run() { compareAndSwap(0, 1); } public static void main(String[] args) throws InterruptedException { TwoThreadsCompetition r = new TwoThreadsCompetition(); r.value = 0; Thread t1 = new Thread(r, "线程1"); Thread t2 = new Thread(r, "线程2"); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(r.value); } }
模拟CAS操作
AtomicInteger类
AtomicInteger加载Unsafe工具,用来直接操作内存数据
用Unsafe来实现底层操作
用volatile修饰value字段,保证可见性
getAndAddInt方法分析
因为CAS只是做和原值相不相等的检查,并没有检查是否被修改。
假设有三个线程,原值是5,线程2把5改为7,线程3又把7改成5,等到第一个线程查看是否是5,发现真的是5,线程1以为没有任何线程对其进行修改,所以线程1就会把这个5改成所期待的值。但是实际上已经有人修改过了。
可以添加版本号,比如说第一个版本的5,第二个版本的5
在原子类的getAndAddInt方法中可以看到,一直在cas部分自旋,如果一直等待锁,就会造成消耗资源的问题。