zoukankan      html  css  js  c++  java
  • 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的非原子性和非线程安全。

  • 相关阅读:
    统计nginx进程占用的物理内存
    使用网络用户命令行工具的/passwordreq:yes
    MSSQL 日期查询 包含NULL值
    错误信息:"OraOLEDB.Oracle" 返回了消息 "ORA-12154: TNS: 无法解析指定的连接标识符
    SQL Server连接Oracle FAIL
    为SSRS配置SMTP服务器身份验证
    约束
    VS2012
    Reporting services
    MSSQL grant权限
  • 原文地址:https://www.cnblogs.com/mjtabu/p/12716341.html
Copyright © 2011-2022 走看看