Java多线程----CAS

Posted 结构化思维wz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程----CAS相关的知识,希望对你有一定的参考价值。

CAS

CAS(Compare And Swap)协议/算法是由硬件实现的。

CAS可以将 read - modify -write 这类的操作转换为 原子操作。

i++ 包括三个原子操作:

  1. 从主内存读取i变量的值
  2. 对i的值加1
  3. 再把加一之后的值保存到主内存

CAS原理:

在把数据更新到主内存时,再次读取主内存变量的值,如果现在变量的值与期望的值(操作起始时读取的值)一致就更新。

理想状态:

并发问题可能的状态:

CAS就是把数据更新到主内存的共享变量前,再次读取主内存共享变量的值,如果现在读取的共享变量的值与期望的值一样就更新:

使用CAS实现线程安全的计数器

package se.high.thread.cas;

/**
 * @author 王泽
 * 使用CAS实现一个线程安全的计数器
 */

public class CasTest {
    public static void main(String[] args) {
        CASCounter cas = new CASCounter();
        for (int i = 0; i < 10000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"----->"+cas.incrementAndGet());
                }
            }).start();
        }
    }
}

class  CASCounter{
    //使用volatile修饰value的值,使线程可见
    volatile private long value;
    public long getValue(){
        return value;
    }
    private boolean compareAndSwap(long expectedValue,long newValue){
        //如果当前value的值与情网的expectedValue值一样,就把当时的Value字段替换为newValue值
        synchronized (this){
            if (value == expectedValue){
                value = newValue;
                return true;
            }else {
                return false;
            }
        }
    }

    //定义自增的方法
    public long incrementAndGet(){
        long oldValue;
        long newValue;
        do {
            oldValue = value;
            newValue = oldValue+1;
        }while(!compareAndSwap(oldValue,newValue));
        return newValue;
    }
}

CAS中的ABA问题

CAS实现原子操作背后有一个假设:共享变量的当前值与当前线程提供的期望值相同,就认为这个变量没有被其他线程修改过。

实际上这个假设不一定总成立。

例如:有一个共享变量 count =0,A线程对count的值修改为10,B线程对count修改为20,C线程对count修改为10; 如果当前线程看到count变量的值为10,我们是否认为count变量的值没有被其他线程更新呢??这种结果是否能接受??

共享变量经历了 A -> B -> A 的更新

是否能够接受ABA的问题跟实现算法有关。如果想要规避ABA问题,可以为共享变量引入一个修订号(时间戳),每次修改共享变量时,相应的修订号就会增加1。

[A,0] -> [B,1] -> [A,2]

这也是AtomicStampedReference类就是基于这种思想产生的。

以上是关于Java多线程----CAS的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程----CAS

Java多线程并发中 CAS 的使用与理解

java多线程 CAS原子引用AtomicReference

Java多线程和并发,CAS(Compare and Swap)

java多线程-CAS原子操作图

6.23Java多线程CAS原子操作