• 原子性,有序性,可见性


    synchronized (原子性  有序性 可见性)  volatile (原子性  可见性)

    1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
    2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的。
    3.volatile仅能实现变量的修改可见性,并不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性。
    4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。 
    5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。

    原子性:所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束

    例如:int i = 1;  该语句为原子操作,因为执行这句话后i的值一定是等于1.

    反例:int i= 0; i++ ; 其中 i++不是原子操作,在多线程中会有线程安全问题,i++其实分为三个步骤,1. 读取变量i的值;2:对i进行加一的操作;3.将计算后的值再赋值给变量i

    synchronized :能保证原子操作。1、锁住主内存,2、执行工作内 3、将工作内存写入主内存。4.释放锁

    但synchronized块不同于真正意义的原子性操作,执行时是可以中断的

    原因:单例模式

    volatile 防止指令重排序 从而保证原子操作

    class Singleton {
    private (volatile) static Singleton instance = null;

    public static Singleton instance() {
    if (instance == null) {
    synchronized (Singleton.class) {
    if (instance == null)
    instance = new Singleton();//step1
    }
    }
    return instance;
    }
    }

    有序性:

    在java内存模型中说过,为了性能优化,编译器和处理器会进行指令重排序;也就是说java程序天然的有序性可以总结为:如果在本线程内观察,所有的操作都是有序的;如果在一个线程观察另一个线程,所有的操作都是无序的。在单例模式的实现上有一种双重检验锁定的方式

    可见性:当一个线程修改了共享变量后,其他线程能够立即得知这个修改

    当线程获取锁时会从主内存中获取共享变量的最新值,释放锁的时候会将共享变量同步到主内存中。从而,synchronized具有可见性。同样的在volatile分析中,会通过在指令中添加lock指令,以实现内存可见性。因此, volatile具有可见性

    参考:https://www.jianshu.com/p/cf57726e77f2

    、https://blog.csdn.net/weixin_45110404/article/details/90453221

    https://blog.csdn.net/niexianglin_csdn/article/details/47361003

  • 相关阅读:
    【Eclipse】Eclipse常用操作
    编码规范系列(一):Eclipse Code Templates设置
    eclipse code templates 设置(eclipse注释模版配置)
    Eclipse代码注释模板-code template
    善用Eclipse的代码模板功能
    ppt五种经典字体组合
    C++对象模型——指向Member Function的指针 (Pointer-to-Member Functions)(第四章)
    (一二一)核心动画基础
    六:二叉树中第k层节点个数与二叉树叶子节点个数
    gdb 调试利器
  • 原文地址:https://www.cnblogs.com/tpcwlilacfover/p/12163876.html
Copyright © 2020-2023  润新知