synchronized实现可见性对比volatile
最近花时间研究了下,如有不正确的地方,欢迎大家批评指正,谢谢。
首先先介绍一下JMM(JAVA内存模型),上图:
java内存模型的工作原理如上图所示,一些被定义的变量都存放在主内存中,当一个线程想要修改一个变量的值时,那么这个变量会从主内存中拷贝到线程的工作内存(CPU缓存)中。之后线程对变量值做了更改,又会重新拷贝回主内存中。大家通过描述也可以看出来这些操作是分步执行的,这样就无法保证可见性和原子性。对于这种情况java也给出了很多解决办法,今天跟大家分享一下我对synchronized以及volatile的理解。
大家知道synchronized是通过加互斥锁来实现原子性的,JMM关于synchronized的两条规定:
- 线程解锁前,必须把共享变量的最新之刷新到主内存中
- 线程加锁前,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意:加锁与解锁需要时同一把锁)
我来简单描叙一下线程执行互斥代码的过程:
- 获得互斥锁
- 清空工作内存
- 从主内存拷贝变量的最新副本到工作内存
- 执行代码
- 将更改后的共享变量的值刷新到主内存
- 释放互斥锁
synchronized从而实现类原子性,也具备内存可见性。
这里多说一下Lock,其实原理跟synchronized类似,但是比synchronized更加灵活,我们会在下一篇博客中详细探讨synchronized的缺陷以及Lock的基本用法。
volatile是如何实现内存可见性的呢?
深入来说:是通过加入内存屏障和禁止重排序优化来实现的。(重排序指单线程中在保证执行结果不变的前提下java虚拟机为了提升处理速度可能会将指令重排,达到最合理化)
- 对volatile变量执行写操作时,会在写操作后加入一条store屏障指令
- 改变线程工作内存中的volatile变量副本的值
- 将改变后的副本的值从工作内存刷新到主内存
- 对volatile变量执行读操作时,会在读操作前加入一条load屏障指令
- 从主内存中读取volatile变量的最新值到线程的工作内存中
- 从工作内存中读取volatile变量的副本
简单来说:volatile变量在每次被线程访问时,都强迫从sy主内存中重读变量的值,而当该变量发生变化时,又会强迫线程将最新的值刷新到主内存。这样在任何时刻,不同的线程总能看到该变量的最新值。从而保证了变量的内存可见性。
synchronized和volatile的比较
- volatile不需要加锁,比synchronized更加轻量级,不会阻塞线程
- 从内存可见性讲,volatile读相当于加锁,volatile写相当于解锁
- synchronized既能保证可见性,又能保证原子性,而volatile只能保证可见性,无法保证原子性
synchronized实现可见性对比volatile相关推荐
- 原创 | 既生synchronized,何生volatile?!
△Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 225篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 在我的博客和公众号中, ...
- 既生synchronized,何生volatile
在作者博客和公众号(Hollis)中,发表过很多篇关于并发编程的文章,之前的文章中我们介绍过了两个在Java并发编程中比较重要的两个关键字:synchronized和volatile 我们简单回顾一下 ...
- java static 可见性_Java多线程 synchronized与可见性的关系以及可见性问题总结
作者:七里香的编程之路 出自:OSCHINA 原文:my.oschina.net/u/4098550/blog/4548274 能保证可见性的措施 除了volatile 可以让变量保证可见性外.hap ...
- 既生synchronized,何生volatile (synchronized与volatile的区别)
既生synchronized,何生volatile (synchronized与volatile的区别) 我们知道,synchronized和volatile两个关键字是Java并发编程中经常用到的两 ...
- 原子变量、volatile、synchronized的可见性和原子性比较
为什么80%的码农都做不了架构师?>>> jdk5提供了java.util.concurrent包,这个包并行功能强大,工具齐全,其中就包括原子变量atomic 那么我们先说说 ...
- Java多线程6:synchronized锁定类方法、volatile关键字及其他
同步静态方法 synchronized还可以应用在静态方法上,如果这么写,则代表的是对当前.java文件对应的Class类加锁.看一下例子,注意一下printC()并不是一个静态方法: public ...
- java基础提升篇:synchronized同步块和volatile同步变量
初遇 Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低 ...
- synchronized同步块和volatile同步变量
Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而 ...
- 1、synchronized、Lock、volatile
1.synchronized 1.1 synchronized原理 修饰代码块 底层实现,通过 monitorenter & monitorexit 标志代码块为同步代码块. 修饰方法 底层实 ...
最新文章
- 25个出众的Web表单范例
- 分布与并行计算—生产者消费者模型RabbitMQ(Java)
- xbox手柄接收器驱动_xbox手柄连接 win10电脑
- 安装PowerDesigner造成Office2007鼠标无法正常使用
- 什么是多核电脑?什么是64位电脑?
- 【转】Galileo伽利略项目-- 数字城市规划和基础设施建模
- Jenkins连接git时出现“Failed to connect to repository : Command ... HEAD“ returned status code 128:”的问题解决
- 文件权限管理命令chmod,chown与文本搜索命令grep
- java打开dex文件_dex文件反编译工具(Dedexer)
- 关系数据库(范式判断、函数依赖、无损分解、正则覆盖)
- 走进小作坊(八)----公益之痒
- 关于 Macbook 外接显示器模糊问题
- pb 如何导出csv_打开CSV格式文件?英雄请留步
- 中文文字检测及识别(ORC)
- python(64位)安装超详细
- 问题 : 我们的征途是星辰大海
- 大顶堆,n个数中找最小的k个数
- 君子生非异也,善假于物也。【借助外力获取能量,主动改善生存环境。】
- 【LeetCode】2022 7月 每日一题
- 使用python matplotlib实现动图绘制
热门文章
- gson格式化参数 对象转Map
- Python 学习日记 第四天
- MySQL Gap Lock问题
- js操作样式自动prefix
- Nubiers to follow
- mybatis 3.2.2_环境搭建
- C++文件操作的6种方式
- maven+svn+hudson+weblogic构建持续集成环境
- 别为iptables日志付出太多-一种Linux防火墙优化方法
- 安装MySQL-python报错 error: command 'gcc' failed with exit status 1解决方法