Discuss / Java / 使用synchronized后,就无需volatile了么?

使用synchronized后,就无需volatile了么?

Topic source

_small_snail

#1 Created at ... [Delete] [Delete and Lock User]

本节在解释synchronized时说到,使用synchronized可保证代码为原子操作,不被其他线程“中断”。听上去,这个机制好像只保证了线程在自己工作内存中处理变量的原子性呢。

至于工作内存处理完成后,再写入主内存的这个过程,synchronized并没有起到作用哈?

如果是的话,那么感觉本节的代码中应该用上volatile才对呀。

中断线程一节中说,用volatile是为了保证工作内存和主内存中的变量值及时的同步,以免其他工作内存读到旧的值。

那不用volatile,只用synchronized,貌似其他工作内存还是可能读到旧的值呀。

dream-reader

#2 Created at ... [Delete] [Delete and Lock User]

synchronized是能保证可见性、有序性和原子性,每次进入synchronized保护的临界区时都会刷新工作内存的变量,退出synchronized会将变化同步到主内存中

Sixmillion

#3 Created at ... [Delete] [Delete and Lock User]

我的理解是:

线程间共享变量需要使用volatile关键字标记,确保每个线程都能读取到更新后的变量值

但是这个更新操作不一定是原子操作,比如之前讲的count+ = 1就分三步完成,倘若没有加锁会导致在被中途中断后,已经load的数据不会更新而是继续执行,从而导致数据无法同步,这是线程同步的问题,不是内存更新的问题。

内存可见性

对java内存模型不熟悉的同学,可以参考这边文章java内存模型

  1. 线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。
  2. 线程获取锁时,JMM会把该线程对应的本地内存置为无效,从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。

作者:占小狼

链接:https://www.jianshu.com/p/19f861ab749e

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

TRUE-TAO

#5 Created at ... [Delete] [Delete and Lock User]

volatile: 保证自己得到的是准确值,也就是每次在工作内存中修改被该关键字标记的字段时候,都会首先返回主内存修改该值,确保外部调用该变量得到的是更新后的值,

synchronized:实际上是一把锁,因为所有自定义的类都默认继承Object类,所以作者会用object作为实例使用,每次

TRUE-TAO

#6 Created at ... [Delete] [Delete and Lock User]

volatile: 保证自己得到的是准确值,也就是每次在工作内存中修改被该关键字标记的字段时候,都会首先返回主内存修改该值,确保外部调用该变量得到的是更新后的值,

synchronized:实际上是一把锁;

Objcet lock=new objcet;(没学习好的“小屁股”肯定会认为objcet哪来,我并没有定义objcet类啊,这个实际上所有自定义类都默认引用了objcet,所以你可以引用objcet所有方法,比如equals())

执行synchronized(Counter.lock)的时候判断是否被锁住,如果被锁住会等待锁释放,然后在获取锁


  • 1

Reply