• java多线程 synchronize 和 volatile 的区别


    java多线程-可见性

    定义:一个线程对主内存的修改可以及时的被其他线程观察到
    
    共享变量在线程间不可见的原因:
    ① 线程交叉执行
    ② 线程交叉执行结合指令重排序
    ③ 共享变量没有在更新后的值没有在工作内存与主存之间及时更新
    

    synchronized的两条规定

    ① 线程释放锁前,必须把共享变量的最新值刷新到主内存当中
    ② 线程获取锁时,将当前线程的本地内存置为无效,从而使用共享变 量时需要从主内存中重新读取最新的值
    

    volatile通过内存屏障和禁止重排序以及禁止中断优化来实现(从CPU的角度去看)

    ① 对volatile类型变量进行写操作时,会在写操作后面加入一条store 屏障指令,将本地内存中的共享变量值刷新到主内存当中;
    ② 读取volatile类型变量时,会在读操作前加入一条load屏障指令,从 主内存中读取共享变量;
    ③ volatile变量在线程每次访问的时候都强迫线程从主内从读取变 量,而当该变量发生变化的时候又会强迫线程将最新的值刷新到主 内存中,这两个操作保证了volatile线程之间的可见性;
    ④ volatile只是保证了共享变量的可见性,并没有保证volatile修 饰的变量的所有操作都是原子操作。对于被volatile修饰的变量 用于get方法和set方法都是线程安全的;此时相当于在get和set 方法上面添加了synchronized关键字。但是对于非原子操作的就 不是线程安全的方法;
    ⑤ volatile适合用于作为检查某个状态标记量以判断是否退出循环 和双重检测机制(安全单例模式)
    

    Synchronized volatile关键字,volatile修饰基本数据类型和自定义类型区别,volatile底层实现

    volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
    volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
    volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
    volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
    volatile标记的变量不会被编译器优化(指令重排);synchronized标记的变量可以被编译器优化
  • 相关阅读:
    KMP的next数组性质运用
    谁说前端不需要懂-Nginx反向代理与负载均衡
    Vue源码
    js学习网站
    CSS文本溢出显示省略号
    Js中带有小数的值相加产生的问题
    使用ueditor的时候,style样式传递到后台时被过滤没了
    实现div里的内容垂直居中
    安装sass报错
    js方法
  • 原文地址:https://www.cnblogs.com/toolbear/p/14848448.html
Copyright © 2020-2023  润新知