最近花时间研究了下,如有不正确的地方,欢迎大家批评指正,谢谢。

首先先介绍一下JMM(JAVA内存模型),上图:

java内存模型的工作原理如上图所示,一些被定义的变量都存放在主内存中,当一个线程想要修改一个变量的值时,那么这个变量会从主内存中拷贝到线程的工作内存(CPU缓存)中。之后线程对变量值做了更改,又会重新拷贝回主内存中。大家通过描述也可以看出来这些操作是分步执行的,这样就无法保证可见性和原子性。对于这种情况java也给出了很多解决办法,今天跟大家分享一下我对synchronized以及volatile的理解。

大家知道synchronized是通过加互斥锁来实现原子性的,JMM关于synchronized的两条规定:

  1. 线程解锁前,必须把共享变量的最新之刷新到主内存中
  2. 线程加锁前,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意:加锁与解锁需要时同一把锁)

我来简单描叙一下线程执行互斥代码的过程:

  1. 获得互斥锁
  2. 清空工作内存
  3. 从主内存拷贝变量的最新副本到工作内存
  4. 执行代码
  5. 将更改后的共享变量的值刷新到主内存
  6. 释放互斥锁

synchronized从而实现类原子性,也具备内存可见性。

这里多说一下Lock,其实原理跟synchronized类似,但是比synchronized更加灵活,我们会在下一篇博客中详细探讨synchronized的缺陷以及Lock的基本用法。

volatile是如何实现内存可见性的呢?

深入来说:是通过加入内存屏障和禁止重排序优化来实现的。(重排序指单线程中在保证执行结果不变的前提下java虚拟机为了提升处理速度可能会将指令重排,达到最合理化)

  • 对volatile变量执行写操作时,会在写操作后加入一条store屏障指令
  1. 改变线程工作内存中的volatile变量副本的值
  2. 将改变后的副本的值从工作内存刷新到主内存
  • 对volatile变量执行读操作时,会在读操作前加入一条load屏障指令
  1. 从主内存中读取volatile变量的最新值到线程的工作内存中
  2. 从工作内存中读取volatile变量的副本

简单来说:volatile变量在每次被线程访问时,都强迫从sy主内存中重读变量的值,而当该变量发生变化时,又会强迫线程将最新的值刷新到主内存。这样在任何时刻,不同的线程总能看到该变量的最新值。从而保证了变量的内存可见性。

synchronized和volatile的比较

  1. volatile不需要加锁,比synchronized更加轻量级,不会阻塞线程
  2. 从内存可见性讲,volatile读相当于加锁,volatile写相当于解锁
  3. synchronized既能保证可见性,又能保证原子性,而volatile只能保证可见性,无法保证原子性

synchronized实现可见性对比volatile相关推荐

  1. 原创 | 既生synchronized,何生volatile?!

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 225篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 在我的博客和公众号中, ...

  2. 既生synchronized,何生volatile

    在作者博客和公众号(Hollis)中,发表过很多篇关于并发编程的文章,之前的文章中我们介绍过了两个在Java并发编程中比较重要的两个关键字:synchronized和volatile 我们简单回顾一下 ...

  3. java static 可见性_Java多线程 synchronized与可见性的关系以及可见性问题总结

    作者:七里香的编程之路 出自:OSCHINA 原文:my.oschina.net/u/4098550/blog/4548274 能保证可见性的措施 除了volatile 可以让变量保证可见性外.hap ...

  4. 既生synchronized,何生volatile (synchronized与volatile的区别)

    既生synchronized,何生volatile (synchronized与volatile的区别) 我们知道,synchronized和volatile两个关键字是Java并发编程中经常用到的两 ...

  5. 原子变量、volatile、synchronized的可见性和原子性比较

    为什么80%的码农都做不了架构师?>>>    jdk5提供了java.util.concurrent包,这个包并行功能强大,工具齐全,其中就包括原子变量atomic 那么我们先说说 ...

  6. Java多线程6:synchronized锁定类方法、volatile关键字及其他

    同步静态方法 synchronized还可以应用在静态方法上,如果这么写,则代表的是对当前.java文件对应的Class类加锁.看一下例子,注意一下printC()并不是一个静态方法: public ...

  7. java基础提升篇:synchronized同步块和volatile同步变量

    初遇 Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低 ...

  8. synchronized同步块和volatile同步变量

    Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而 ...

  9. 1、synchronized、Lock、volatile

    1.synchronized 1.1 synchronized原理 修饰代码块 底层实现,通过 monitorenter & monitorexit 标志代码块为同步代码块. 修饰方法 底层实 ...

最新文章

  1. 25个出众的Web表单范例
  2. 分布与并行计算—生产者消费者模型RabbitMQ(Java)
  3. xbox手柄接收器驱动_xbox手柄连接 win10电脑
  4. 安装PowerDesigner造成Office2007鼠标无法正常使用
  5. 什么是多核电脑?什么是64位电脑?
  6. 【转】Galileo伽利略项目-- 数字城市规划和基础设施建模
  7. Jenkins连接git时出现“Failed to connect to repository : Command ... HEAD“ returned status code 128:”的问题解决
  8. 文件权限管理命令chmod,chown与文本搜索命令grep
  9. java打开dex文件_dex文件反编译工具(Dedexer)
  10. 关系数据库(范式判断、函数依赖、无损分解、正则覆盖)
  11. 走进小作坊(八)----公益之痒
  12. 关于 Macbook 外接显示器模糊问题
  13. pb 如何导出csv_打开CSV格式文件?英雄请留步
  14. 中文文字检测及识别(ORC)
  15. python(64位)安装超详细
  16. 问题 : 我们的征途是星辰大海
  17. 大顶堆,n个数中找最小的k个数
  18. 君子生非异也,善假于物也。【借助外力获取能量,主动改善生存环境。】
  19. 【LeetCode】2022 7月 每日一题
  20. 使用python matplotlib实现动图绘制

热门文章

  1. gson格式化参数 对象转Map
  2. Python 学习日记 第四天
  3. MySQL Gap Lock问题
  4. js操作样式自动prefix
  5. Nubiers to follow
  6. mybatis 3.2.2_环境搭建
  7. C++文件操作的6种方式
  8. maven+svn+hudson+weblogic构建持续集成环境
  9. 别为iptables日志付出太多-一种Linux防火墙优化方法
  10. 安装MySQL-python报错 error: command 'gcc' failed with exit status 1解决方法