《Java并发编程实战》读书笔记·Part1

重排序(Reordering)

在没有同步的情况下,编译器、处理器有可能对语句执行的顺序进行改变,这种情况叫做重排序。因为执行顺序的未知产生的时间差,在时间敏感的情况下对某些变量进行的读取操作就有可能会出现错误。比如说下面这个例子:
Listing 3.1

因为重排序的存在,main()方法当中的三条语句执行的先后顺序未知。程序输出number的结果可能为42,而不是0(甚至线程不会终止)。
上述程序只涉及到两个线程和两个变量,即便如此也有可能因为重排序而产生意想不到的错误。要避免重排序产生的影响,必须采用合适的同步手段。事实上,一旦变量有可能在不同线程之间传递,我们都应该采用相应的手段来避免类似问题——对语句执行次序敏感的问题。

非原子的64位操作

Java内存模型要求,变量的读取操作和写入操作都必须是原子操作,但对于非volatile类型的long和double变量,JVM允许将64位的读操作或者写操作分解为两个32位的操作。当读取一个非volatile类型的long变量时 ,如果对该变量的读和写操作在不同的线程中操作,那么很有可能会读到一个值的高32位和另一个值的低32位。

Volatile变量

为了避免上述数据过期问题,Java提供了一种稍弱的同步机制即volatile变量。volatile变量使得在不同线程之间发生的改变总能及时地反映在每个线程当中。当一个变量被声明为volatile变量,编译器和运行时环境会注意到这个变量是被共享的,并且不会对涉及这个变量的操作进行重排序。volatile变量不会被缓存在寄存器或者其他对处理器不可见的地方,因此针对该变量的改变总能及时地更新。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值