Volatile关键字--最轻量级的同步机制

Volatile关键字--最轻量级的同步机制

  • 1.保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)

    例如:如果一个old value -->修改为 new value ,这时的 new value 可以被其他的线程看到。

  • 2.volatile 不是线程安全的,只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性。(不能保证原子性)

最常使用场景:一写多读

代码演示Volatile的可见性

public class VolatileCase {
    //未加volatile关键字
    private static boolean ready = false;
    private static int number = 0;
    private static class ThreadInfo extends  Thread{
        @Override
        public void run() {
            System.out.println("Thread start");
            while (!ready);
            System.out.println("number:"+number+"----ready:"+ready+"Thread end");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        new ThreadInfo().start();
        Thread.sleep(100);
        ready = true;
        number = 123;
        Thread.sleep(100);
        System.out.println("main end");
    }
}

未加Volatile关键字运行结果:

加上Volatile关键字后:

    //加volatile关键字
    private volatile static boolean ready = false;

加上Volatile关键字运行结果:

 

综上:

证实Volatile的可见性:当一个线程修改一个Volatile修饰的变量时,其他线程可以实时看到。

代码演示Volatile的非原子性:

public class VolatileCase {
    //Volatile关键字
    private volatile int count = 0;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void inCount(){
            count++;
    }

    private static class ThreadInfo extends Thread{
        private VolatileCase vc;
        public ThreadInfo(VolatileCase vc){
            this.vc = vc;
        }
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                vc.inCount();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        VolatileCase vc = new VolatileCase();
        ThreadInfo threadInfo1 = new ThreadInfo(vc);
        ThreadInfo threadInfo2 = new ThreadInfo(vc);
        threadInfo1.start();
        threadInfo2.start();
        Thread.sleep(100);
        System.out.println("main end:"+vc.getCount());
    }
}

第一次运行结果:

 第二次运行结果:

 正确的运行结果应该是20000的,但是每次结果都少于20000,证实Volatile的非原子性和非线程安全。

原文地址:https://www.cnblogs.com/mjtabu/p/12716341.html