对象的共享——《Java并发编程实战》学习笔记二

    倘若synchronize只能用于实现原子性或确定临界区(Critical Section)。那么线程A修改了某个共享参数后,线程B可能获取到的参数不是最新的,同样会出现问题。因此,同步还有另外一个重要方面:内存可见性(Memory Visibility)。

    为了保证多个线程间对内存写入操作的可见性,必须使用同步机制。

    1、失效数据:共享数据在多个线程下,缺乏同步时,2个共享数据可能出现4种不同的复杂情况。但是,这个失效值是由之前某个线程设置的值,而不是一个随机值。这种称为最低安全性(out-of-thin-airsafety)。

    2、非原子的64位操作:最低安全性适用于大多数变量。但是非volatile的64位数值变量(double和long)。Java内存模型要求,变量的读取和写入操作必须是原子操作,但对于非volatile类型的long和double变量,JVM会分解为两个32位的操作。针对64位变量的读写操作在不同线程中执行,那么就可能读取到某个值得高32位,另一个值得低32位。

    因此,针对共享的和可变的状态操作时,需要使用同步机制保护。

    3、加锁和可见性:核心是锁的happends-before原则,同一个锁的unlock操作happend-before锁的lock操作。例:A、B线程先后进入由同一个锁保护的同步代码块时,当B执行由锁保护的同步代码块时,可以看到A之前在同一个代码块中的所有操作结果。注意单例中的DCL。

    4、volatile和可见性:核心是volatile的happends-before原则,对一个volatile变量的写操作happend-before此变量的任意操作(包括写操作)。例:线程A、B依次写入和读取volatile变量,在写入volatile变量之前对A可见的所有变量的值,在B读取volatile变量后,对B都是可见的。因此,从内存可见性角度来看,写入volatile变量相当于退出同步代码块,而读取volatile变量相当于进入同步代码块。

    因此,加锁机制确保可见性和原子性,而volatile变量只能确保可见性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值