• 三、原子变量与CAS算法


    原子变量:jdk1.5 后 java.util.concurrent.atomic 包下提供了常用的原子变量:

    - AtomicBoolean
    - AtomicInteger 
    - AtomicLong
    - AtomicReference 
    - AtomicIntegerArray
    - AtomicLongArray 
    - AtomicMarkableReference 
    - AtomicReferenceArray 
    - AtomicStampedReference
    

    1.以上类中的变量都是volatile类型:保证内存可见性
    2.CAS算法:保证数据的原子性

    CAS (Compare-And-Swap) 算法:是操作系统硬件对并发操作共享数据的支持,用于管理对共享数据的并发访问。
    CAS 是一种无锁的非阻塞算法的实现。
    CAS包含三个操作数

    内存值 V 
    预估值 A 
    更新值 B
    
    当且仅当,V==A 时,才将 B 的只值赋给 A,否则,将不做任何操作。  //(CAS算法的一个特性)
    

    代码示例:

    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 volatile int serialNumber = 0;
    
        private AtomicInteger serialNumber = new AtomicInteger(0);
    
        @Override
        public void run() {
    
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
            }
    
            System.out.println(getSerialNumber());
        }
    
        public int getSerialNumber(){
            return serialNumber.getAndIncrement();//实现i++操作
        }
    }
    

    [注] i++ 的实现原理

    i++ 的原子性问题:i++ 的实际上分为三个步骤:"读 - 改 - 写"
    即,i++的底层实际上是:
    	int temp=i; //temp 是个临时变量
    	i=i+1;
    	i=temp;
    

    模拟CAS算法 :

    CAS的流程:获取 —> 比较 —> 设置

    public class TestCompareAndSwap {
        public static void main(String[] args) {
            final CompareAndSwap cas=new CompareAndSwap();
    
            for(int i=0;i<10;i++){
                new Thread(new Runnable(){
                    @Override
                    public void run() { 
                        int expectedValue=cas.get(); //每次执行前先获取内存中的值
                        boolean isTrue=cas.compareAndSet(expectedValue, (int)(Math.random()*101));
                        System.out.println(isTrue);
                    }
                }).start();
            }
        }
    }
    
    class CompareAndSwap{
        //内存值
        private int value;
    
        //获取内存值
        public synchronized int get(){
            return value;
        }
    
        //比较
        public synchronized boolean compareAndSwap(int expectedValue,int newValue){
            int oldValue=value;//线程读取内存值,与预估值比较
            if(oldValue==expectedValue){
                this.value=newValue;
                return true;
            }
            return false;
        }
      
      	//设置
      	public synchronized boolean compareAndSet(int expectedValue,int newValue){
        	return expectedValue == compareAndSwap(expectedValue,newValue);
      	}
    }
    
  • 相关阅读:
    使用 cordova-plugin-wechat 分享返回后闪退解决方法
    恢复删除的表
    移动端还原设计图
    js文本差异比较
    windows使用nvm安装nodejs后升级npm报错
    windows添加右键菜单"在此处打开cmd窗口"
    cordova热更新
    js变量提升
    c# 判断字符串是否是日期格式需要注意的一点小问题
    剑指offer_和为S的两个数字
  • 原文地址:https://www.cnblogs.com/zongheng14/p/10703822.html
Copyright © 2020-2023  润新知