volatile关键字与内存可见性&原子变量与CAS算法

爷,独闯天下 提交于 2020-04-04 11:30:46

1 .volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见

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

3 .模拟CAS算法

TestVolatile

package com.aff.juc;
/*
1.volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见
                  相较于synchronized是一种较为轻量级的同步策略
注意: volatile不具备"互斥性" 
     不能保证变量的原子性 
*/
public class TestVolatile {
    public static void main(String[] args) {
        ThreadDemo td = new ThreadDemo();
        new Thread(td).start();
        while(true){
        //    synchronized (td) {//同步锁,刷新  效率极低
            if(td.isFlag()){
                System.out.println("------------");
                break;
                }
            //}
        }
    }
}

class ThreadDemo implements Runnable {
    private  volatile boolean flag = false;

    @Override
    public void run() {
        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
        flag = true;
        System.out.println("flag=" + isFlag());
    }

    public boolean isFlag() {
        return flag;
    }
}

 

TestAtomicDemo

package com.aff.juc;

import java.util.concurrent.atomic.AtomicInteger;

/*
 *
 *1.  i++  的原子性问题: i++  操作实际上分为三步 读-改-写
 *            int i = 10;
 *            i = i++;//10
 *
 *            int temp= i;
 *            i = i +1;
 *            i = temp;
 *2.  原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量 
 *                    1.具有volatile的特性(内存可见性)    private volatile int value;
 *                    2.CAS算法保证数据的 原子性
 *                              CAS算法是硬件对于并发操作共享数据的支持
 *                              CAS包含了三个操作数:
 *                                     V内存值
 *                                     A预估值
 *                                     B更新值
 *                              当且仅当 V==A, V=B   (只有当V和A相等才把B的值赋给V),否则,不做任何操作      
 *                             
 */
public class TestAtomicDemo {
    public static void main(String[] args) {
        AtomicDemo ad = new AtomicDemo();
        new Thread(ad).start();
        for (int i = 0; i < 10; i++) {
            new Thread(ad).start();
        }
    }
}

class AtomicDemo implements Runnable {
    // private int serialNumber = 0;
    private AtomicInteger serialNumber = new AtomicInteger();// 使用原子变量

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (Exception e) {
        }
        //使用原子变量就不会出现重复的了
        System.out.println(Thread.currentThread().getName() + ":" + getSerialNumber());
        
    }

    public int getSerialNumber() {
        // return serialNumber++;
        return serialNumber.getAndIncrement();
    }
}

 

TestCompareAndSwap

package com.aff.juc;

//模拟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 b = cas.compareAndSet(expectedValue, (int) (Math.random() * 100));
                    System.out.println(b);
                }
            }).start();
        }
    }
}

class CompareAndSwap {
    private int value;

    // 获取内存值
    public synchronized int get() {
        return value;
    }

    // 比较
    public synchronized int CompareAndSwap(int expectedValue, int newValue) {// expectedValue
                                                                             // 预估值
        int oldValue = value;
        if (oldValue == expectedValue) {// 旧的内存值和预估值进行比较
            this.value = newValue;// 替换
        }
        return oldValue;
    }

    // 设置
    public synchronized boolean compareAndSet(int expectedValue, int newValue) {
        return expectedValue == CompareAndSwap(expectedValue, newValue);
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!