zoukankan      html  css  js  c++  java
  • 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标记的变量可以被编译器优化
  • 相关阅读:
    MySql 插入(insert)性能测试 zt 武胜
    mysql日期 武胜
    Some Useful Extension Methods On IList<T> zt 武胜
    SQL语句 武胜
    MySql bulk load zt 武胜
    C# 结构体初始化 武胜
    备忘 武胜
    C# 批量插入Mysql zt 武胜
    Use C# to get JSON Data from the Web and Map it to .NET Class => Made Easy! 转 武胜
    开发例子 转http://www.google.com.hk/search?newwindow=1&safe=strict&client=firefoxa&hs=Gzw&rls=org.mozilla%3AzhCN%3Aofficial&q=%E5%8D%83%E5%8F%91&oq=%E5% 武胜
  • 原文地址:https://www.cnblogs.com/toolbear/p/14848448.html
Copyright © 2011-2022 走看看