使用synchronized后,就无需volatile了么?
Topic sourcesynchronized是能保证可见性、有序性和原子性,每次进入synchronized保护的临界区时都会刷新工作内存的变量,退出synchronized会将变化同步到主内存中
我的理解是:
线程间共享变量需要使用
volatile
关键字标记,确保每个线程都能读取到更新后的变量值
但是这个更新操作不一定是原子操作,比如之前讲的count+ = 1
就分三步完成,倘若没有加锁会导致在被中途中断后,已经load
的数据不会更新而是继续执行,从而导致数据无法同步,这是线程同步的问题,不是内存更新的问题。
内存可见性
对java内存模型不熟悉的同学,可以参考这边文章java内存模型。
- 线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。
- 线程获取锁时,JMM会把该线程对应的本地内存置为无效,从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。
作者:占小狼
链接:https://www.jianshu.com/p/19f861ab749e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
volatile: 保证自己得到的是准确值,也就是每次在工作内存中修改被该关键字标记的字段时候,都会首先返回主内存修改该值,确保外部调用该变量得到的是更新后的值,
synchronized:实际上是一把锁,因为所有自定义的类都默认继承Object类,所以作者会用object作为实例使用,每次
volatile: 保证自己得到的是准确值,也就是每次在工作内存中修改被该关键字标记的字段时候,都会首先返回主内存修改该值,确保外部调用该变量得到的是更新后的值,
synchronized:实际上是一把锁;
Objcet lock=new objcet;(没学习好的“小屁股”肯定会认为objcet哪来,我并没有定义objcet类啊,这个实际上所有自定义类都默认引用了objcet,所以你可以引用objcet所有方法,比如equals())
执行synchronized(Counter.lock)的时候判断是否被锁住,如果被锁住会等待锁释放,然后在获取锁
- 1
_small_snail
本节在解释synchronized时说到,使用synchronized可保证代码为原子操作,不被其他线程“中断”。听上去,这个机制好像只保证了线程在自己工作内存中处理变量的原子性呢。
至于工作内存处理完成后,再写入主内存的这个过程,synchronized并没有起到作用哈?
如果是的话,那么感觉本节的代码中应该用上volatile才对呀。
中断线程一节中说,用volatile是为了保证工作内存和主内存中的变量值及时的同步,以免其他工作内存读到旧的值。
那不用volatile,只用synchronized,貌似其他工作内存还是可能读到旧的值呀。