Synchronized和Volatile的区别

2 篇文章 0 订阅

共性:volatile与synchronized都用于保证多线程中数据的安全性

1、Java语言为了解决并发编程中存在的原子性、可见性和有序性问题,提供了一系列和并发处理相关的关键字,比如 synchronized、volatile、final、concurren 包等。

2、synchronized 通过加锁的方式,使得其在需要原子性、可见性和有序性这三种特性的时候都可以作为其中一种解决方案,看起来是“万能”的。的确,大部分并发控制操作都能使用 synchronized 来完成。

3、volatile 通过在 volatile 变量的操作前后插入内存屏障的方式,保证了变量在并发场景下的可见性和有序性

4、volatile 关键字是无法保证原子性的,而 synchronized 通过 monitorenter 和monitorexit 两个指令,可以保证被 synchronized 修饰的代码在同一时间只能被一个线程访问,即可保证不会出现CPU时间片在多个线程间切换,即可保证原子性。

------什么是可见性和原子性?

【1】可见性

说的是一个线程如果更改了某个变量的值,其他线程能够立刻知道这个变量更改后的值。

【2】原子性

一个操作要么全做,要么全不做,就像不可分割的原子一样。

【3】有序性

为了提高执行效率,java 中的编译器和处理器可以对指令进行重新排序,重新排序会影响多线程并发的正确性,有序性就是要保证不进行重新排序(保证线程操作的执行顺序)。

一.Volatile

Volatile可以看做是一个轻量级的synchronized,它可以在多线程并发的情况下保证变量的“可见性”,什么是可见性?

-------就是在一个线程的工作内存中修改了该变量的值,该变量的值能立即回显到主内存中,从而保证所有的线程看到这个变量的值是最新的。

所以在处理同步问题上它大显作用,而且它的开销比synchronized小、使用成本更低。volatile用于修饰变量。

二.Synchronized

synchronized 叫做同步锁,是Lock的一个简化版本,由于是简化版本,那么性能肯定是不如Lock的,不过它操作起来方便,只需要用它修饰一个方法或者一段代码块,那么这段代码就是同步的了,所有线程对这块区域的访问必须先持有锁才能进入,否则,则拦截在外面,等待正在持有锁的线程处理完毕再获取锁进入,正因为它基于这种阻塞的策略,所以它的性能不太好,但是由于操作上的优势,只需要简单的声明一下即可,而且被它声明的代码块也是具有操作的原子性。

因为synchronized 保证了在同一时刻,只能有一个线程执行同步代码块,所以执行同步代码块的时候相当于是单线程操作了,那么线程的可见性、原子性、有序性(线程之间的执行顺序)它都能保证了。

三.总结

  • 1.volatile 仅能使用在变量级别,synchronized 则可以使用在变量、方法、类级别、代码块上。
  • 2.volatile 仅仅能实现变量修改可见性,并不能保证原子性,volatile 表示变量在 CPU 的寄存器中是不确定的,必须从主存中读取,synchronized 可以实现变量的修改可见性和原子性。
  • 3.volatile 不会造成线程阻塞,synchronized 可能会造成线程阻塞。
  • 4.volatile 标记的变量不会被编译器优化,synchronized 标记的变量可以被编译器优化。
  • 5.volatile 修饰的变量,jvm 每次都从主内存中读取,而不会从寄存器(工作内存)中读取。synchronized 表示只有一个线程可以获取作用 对象 的锁,执行代码,阻塞其他线程。
  • volatie 仅能实现变量的可见性,无法保证变量操作的原子性。而synchronized可以实现变量的可见性与原子性。
  • 7
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值