一、背景

提起并发编程,我们不得不说起 volatilesynchronized 这两个关键字,这两个关键字也是面试中常常被问到的,下面我们分别介绍一下这两个关键字以及二者的异同

首先我们先理解关于线程安全的两个名词:内存可见 和 执行顺序

内存可见:顾名思义就是线程执行结果在内存中对其它线程的可见性

执行顺序:控制代码的执行顺序及是否可以并发执行

二、volatile

volatile 解决的是内存可见性问题

2.1 volatile 原理

volatile原理是基于CPU内存屏障指令实现的

2.2 volatile 修饰的变量可见性

volatile是变量修饰符,其修饰的变量具有内存可见性

一般情况下线程在执行时,Java中为了加快程序的运行效率,会先把主存数据拷贝到线程本地(寄存器或是CPU缓存),操作完成后再把结果从线程本地缓存刷新到主存中,这样就会导致修改后放入变量结果同步到主存中需要一个过程,而此时另外的线程看到的还是修改之前的变量值,这样就会导致不一致

为了解决上述多线程中内存可见的问题,引入了 volatile 关键字,那么它为什么可以解决内存可见性问题呢?

答案: volatile 它会使得所有对 volatile 变量的读写都会直接读写主存,而不是先读写线程本地缓存,这样就保证了变量的内存可见性

2.3 volatile 禁止指令重排 

volatile可以禁止进行指令重排

指令重排: 处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证各个语句的执行顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。指令重排序不会影响单个线程的执行,但是会影响到线程并发执行时的正确性

线程执行到volatile修饰变量的读写操作时,其他线程对这个变量的操作肯定已经完成了,且结果已经同步到了主存中,即对其他的线程可见,本线程再对该变量操作完全没有问题的

2.4 volatile 使用范围

volatile关键字仅能实现对原始变量(如boolen、 short 、int 、long等)操作的原子性,不能保证复合操作的原子性,比如 i++

i++,实际上是由三个原子操作组成:read i; inc; write i,假如多个线程同时执行i++,volatile只能保证他们操作的i是同一块内存,但不能保证i结果的正确性,原因如下:

比如有两个线程A和B对volatile修饰的i进行i++操作,i的初始值是0,A线程执行i++时刚读取了i的值0,就切换到B线程了,B线程(从内存中)读取i的值也为0,然后就切换到A线程继续执行i++操作,完成后i就为1了,接着切换到B线程,因为之前已经读取过了,所以继续执行i++操作,最后的结果i就为1了,A和B线程同步到主存中的i的值都是1

2.5 volatile 使用场景

1、 对变量的写入操作不依赖变量的当前值,或者只有单个线程更新变量的值

2、 该变量没有包含在具有其他变量的不变式中

三、synchronized

synchronized 既解决了内存可见性问题,又解决了执行顺序问题

synchronized 可以修饰代码块或方法,既可以保证可见性,又能够保证原子性

synchronized 锁具体实现过程:https://blog.csdn.net/ywlmsm1224811/article/details/108322059

3.1 synchronized 原理

synchronized 是基于 monitor 实现的

3.2 synchronized 修饰的代码块或方法保证内存可见性

通过synchronized或者Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存中

3.3 synchronized 修饰的代码块或方法保证原子性

线程要么不执行(线程没有获取到对象锁),线程要么执行到底(线程获取到了对象锁),直到执行完释放锁

3.4 synchronized 使用范围

synchronized 不仅能修饰代码块,还可以修饰方法

3.5 synchronized 使用场景

需要控制多线程访问的方法或者更新的变量

四、volatile 和 synchronized 异同点

4.1 相同点

volatile 和 synchronized 都保证了内存可见性

4.2 不同点

1、volatile仅能使用在变量级别,synchronized则可以使用在变量、方法、和类级别的

2、volatile仅能实现变量的修改可见性,不能保证原子性,而synchronized则可以保证变量的修改可见性和原子性

3、volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞

4、volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化

5、由于 4 中的区别,在某些情况下 volatile 的性能优于 synchronized

五、总结

通过上面对 volatile 和 synchronized 的了解我们知道,volatile 是绝对不能替代 synchronized 的,最主要的原因就是 volatile 不能保证操作的原子性

参考:

https://blog.csdn.net/SEU_Calvin/article/details/52370068

https://blog.csdn.net/suifeng3051/article/details/52611233

https://blog.csdn.net/suifeng3051/article/details/52611310

volatile 和 synchronized 详解相关推荐

  1. 【java】java 关键字: synchronized详解

    1.概述 转载:关键字: synchronized详解 [Java]Synchronized 有几种用法 [java] 从hotspot底层对象结构理解锁膨胀升级过程 [java]动态高并发时为什么推 ...

  2. synchronized详解

    目录 1 简介 2 用法 3 原理 3.1 Monitor对象 3.2 对象的内存布局 3.2.1 对象头 3.2.2 实例数据 3.2.3 对齐填充 4 synchronized优化 4.1 偏向锁 ...

  3. Java synchronized详解

    Java synchronized详解 第一篇: 使用synchronized 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--s ...

  4. 多线程——synchronized详解

    多线程--synchronized详解 "当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下 的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用 ...

  5. 并发编程专题——第二章(并发编程之Synchronized详解)

    日常中我们都会用到Synchronized关键字,但是面试就喜欢问这些,你说不重要吧,面试就不问了,你说重要吧,工作中除了高并发之外,很少能在业务代码中使用到的.所以笔者顶着风险,写下此篇对Synch ...

  6. Volatile关键字的详解

    Volatile的详解 简介 Volatile:易变的 测试用例一:非Volatile变量 测试用例二:Volatile变量 测试用例三:非Volatile变量 测试用例四:Volatile变量 Vo ...

  7. 并发编程四 synchronized详解

    一 设计同步器的意义 多线程编程中,有可能会出现多个线程同时访问同一个共享.可变资源的情况,这个资源我们称之其为临界资源:这种资源可能是:对象.变量.文件等. 共享:资源可以由多个线程同时访问 可变: ...

  8. Synchronized 详解

    语法 synchronized(锁对象) // 线程1, 线程2(blocked) {临界区 } 注意 如果 t1 synchronized(obj1) 而 t2 synchronized(obj2) ...

  9. java架构升级_java架构之路(多线程)synchronized详解以及锁的膨胀升级过程

    上几次博客,我们把volatile基本都说完了,剩下的还有我们的synchronized,还有我们的AQS,这次博客我来说一下synchronized的使用和原理. synchronized是jvm内 ...

最新文章

  1. mybatis-mysql常用操作
  2. 9款jQuery插件为你的网站增加亮点
  3. 老干妈如今做到这么大,为什么她就是没遇到竞敌?
  4. 汉字转html实体符号js_html实体编码遇上js代码
  5. 领导想提拔别人,让我让位置,我该怎么办?
  6. java中的银行界面开发_ATM机银行项目java图形界面
  7. java实现记住密码_java简单实现记住密码功能
  8. 超实用的开源项目—如何将WiFi密码转成二维码进行共享
  9. the little schemer 笔记(8)
  10. Nginx配置域名重定向/域名跳转
  11. C++字符,字符串,数字,小写,大写的相互转化
  12. ubuntu20.04关闭内核自动更新
  13. MATLAB图形标注
  14. js获取当前服务器的ip
  15. 无向图的关联矩阵JAVA_图的矩阵表示无向图及有向图的关联矩阵.doc
  16. 生日悖论 Birthday Paradox 至少有两人同一天生日概率
  17. ACM-ICPC 2018沈阳赛区网络预选赛
  18. 关于泛微E9 OA系统手机端无法使用的抢救过程
  19. c语言计算器图形界面v1.0,vc+easy x
  20. 2019深圳中学学区房划分

热门文章

  1. Equitability, mutual information, and the maximal information coefficient
  2. 卡尔曼滤波(Kalman Filtering)——(6)MATLAB仿真(保姆级)
  3. html链接怎么加颜色,html怎么设置超链接颜色
  4. 走近棒球运动·巴尔的摩金莺队·MLB棒球创造营
  5. GIS坐标系统(三):投影坐标系统/地图投影
  6. 大数据时代下的企业战略
  7. 10月31今天万圣节,好玩的一天,不信看google首页的图片
  8. C语言入门·定义变量及类型转换
  9. 香港免费电视有哪些? 香港有哪些免费网络电视?
  10. 华为网络配置(NAT)