JUC学习02:CAS 算法

JUC学习02:CAS 算法

参考文章:https://www.cnblogs.com/linkworld/p/7819270.html;已经描述很清晰

 

i++ 的原子性问题

  1. i++的操作实际上分为三个步骤: "读-改-写";
  2. 原子性: 就是"i++"的"读-改-写"是不可分割的三个步骤;
  3. 原子变量: JDK1.5 以后, java.util.concurrent.atomic包下,提供了常用的原子变量;
    • 原子变量中的值,使用 volatile 修饰,保证了内存可见性;
    • CAS(Compare-And-Swap) 算法保证数据的原子性;
int i = 10;
i = i++;  // 此时, i=10

执行步骤:
int temp = i;
i = i + 1;
i = temp;


// 测试类
public class TestAtomicDemo{
    public static void main(String[] args){

        AtomicDemo ad = new AtomicDemo();

        for(int i=0; i < 10; i++){
            new Thread(ad).start();
        }
    }
}

class AtomicDemo implements Runnable{
    private int serialNumber = 0;

    public void run(){

        try{
            Thread.sleep(200);
        }catch(InterruptedException e){

        }

        System.out.println(Thread.currentThread().getName() + ":" + getSerialNumber());
    }

    public int getSerialNumber(){
        return serialNumber++;
    }
}

// 改进: 使用原子变量
class AtomicDemo implements Runnable{

    private AtomicInteger serialNumber = new AtomicInteger();

    public void run(){
        try{
            Thread.sleep(200);
        }catch(InterruptedException e){

        }

        System.out.println(Thread.currentThread().getName()+":"+getSerialNumber());
    }

    public int getSerialNumber(){
        // 自增运算
        return serialNumber.getAndIncrement();
    }
}

CAS 算法

  • CAS(Compare-And-Swap) 算法是硬件对于并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于
    管理对共享数据的并发访问;
  • CAS 是一种无锁的非阻塞算法的实现;
  • CAS 包含了三个操作数:
    • 需要读写的内存值: V
    • 进行比较的预估值: A
    • 拟写入的更新值: B
    • 当且仅当 V == A 时, V = B, 否则,将不做任何操作;
// 模拟CAS 算法
class CompareAndSwap{
    private int value;

    // 获取内存值
    public synchronized int get(){
        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); } } public class TestCompareAndSwap{ public static void main(String[] args){ final CopareAndSwap cas = new CompareAndSwap(); for(int i=0; i<10; i++){ // 创建10个线程,模拟多线程环境 new Thead(new Runnable(){ public void run(){ int expectedValue = cas.get(); boolean b = cas.compareAndSet(expectedValue, (int)(Math.random()*100)); System.out.println(b); } }).start(); } } }

猜你喜欢

转载自www.cnblogs.com/wobuchifanqie/p/11815684.html
今日推荐