zoukankan      html  css  js  c++  java
  • volatile

    任何被volatile修饰的变量,都不拷贝副本到工作内存,任何修改都及时写在主存。
    因此对于Valatile修饰的变量的修改,所有线程马上就能看到,
    但是volatile不能保证对变量的修改是有序的。什么意思呢?假如有这样的代码:
    Java代码 public class VolatileTest{
    public volatile int a;
    public void add(int count){
    a=a+count;
    }
    }
    当一个VolatileTest对象被多个线程共享,
    a的值不一定是正确的,
    因为a=a+count包含了好几步操作,而此时多个线程的执行是无序的,
    因为没有任何机制来保证多个线程的执行有序性和原子性。
    volatile存在的意义是,任何线程对a的修改,
    都会马上被其他线程读取到,因为直接操作主存,没有线程对工作内存和主存的同步
    。所以,volatile的使用场景是有限的,在有限的一些情形下可以使用 volatile 变量替代锁。
    要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:
    1)对变量的写操作不依赖于当前值。
    2)该变量没有包含在具有其他变量的不变式中
    volatile只保证了可见性,所以Volatile适合直接赋值的场景,
    如Java代码
    public class VolatileTest{
    public volatile int a;
    public void setA(int a){
    this.a=a;
    }
    }
    public class VolatileTest{
    public volatile int a;
    www.gzlij.com public void setA(int a){
    this.a=a;
    }
    }
    4在没有volatile声明时,多线程环境下,a的最终值不一定是正确的,
    因为this.a=a;涉及到给a赋值和将a同步回主存的步骤,这个顺序可能被打乱。
    如果用volatile声明了,读取主存副本到工作内存和同步a到主存的步骤,
    相当于是一个原子操作。
    所以简单来说,volatile适合这种场景:一个变量被多个线程共享,线程直接给这个变量赋值。
    这是一种很简单的同步场景,这时候使用volatile的开销将会非常小。
     
  • 相关阅读:
    feign远程调用问题
    java8--stream
    feign业务组件远程请求 /oauth/token
    redis实现自增序列
    MySQL数据库 相关知识点
    netty
    spring的启动流程及bean的生命周期
    MethodHandleVS反射
    并发与并行
    关于注解的思考
  • 原文地址:https://www.cnblogs.com/erma0-007/p/8645474.html
Copyright © 2011-2022 走看看