Atomicity and volatility

Atomicity applies to "simple operations" on primitive types except for longs and doubles. 

Reading and writing primitive variables other than long and double is guaranteed to go to 

and from memory as indivisible (atomic) operations. However, the JVM is allowed to 

perform reads and writes of 64- bit quantities (long and double variables) as two separate 

32-bit operations, raising the possibility that a context switch could happen in the middle of a 

read or write, and then different tasks could see incorrect results (this is sometimes called 

word tearing, because you might see the value after only part of it has been changed). 

However, you do get atomicity (for simple assignments and returns) if you use the volatile 

keyword when defining a long or double variable (note that volatile was not working 

properly before Java SE5). Different JVMs are free to provide stronger guarantees, but you 

should not rely on platform-specific features.  

Atomic operations are thus not interruptible by the threading mechanism. Expert 

programmers can take advantage of this to write lock-free code, which does not need to be 

synchronized. But even this is an oversimplification. Sometimes, even when it seems like an 

atomic operation should be safe, it may not be. Readers of this book will typically not be able 

to pass the aforementioned Goetz Test, and will thus not be qualified to try to replace 

synchronization with atomic operations. Trying to remove synchronization is usually a sign 

of premature optimization, and will cause you a lot of trouble, probably without gaining 

much, or anything.  

On multiprocessor systems (which are now appearing in the form of multicore processors—

multiple CPUs on a single chip), visibility rather than atomicity is much more of an issue 

than on single-processor systems. Changes made by one task, even if they’re atomic in the 

sense of not being interruptible, might not be visible to other tasks (the changes might be 

temporarily stored in a local processor cache, for example), so different tasks will have a 

different view of the application’s state. The synchronization mechanism, on the other hand, 

forces changes by one task on a multiprocessor system to be visible across the application. 

Without synchronization, it’s indeterminate when changes become visible.  

The volatile keyword also ensures visibility across the application. If you declare a field to be 

volatile, this means that as soon as a write occurs for that field, all reads will see the change. 

This is true even if local caches are involved—volatile fields are immediately written through 

to main memory, and reads occur from main memory.  

It’s important to understand that atomicity and volatility are distinct concepts. An atomic 

operation on a non-volatile field will not necessarily be flushed to main memory, and so 

another task that reads that field will not necessarily see the new value. If multiple tasks are 

accessing a field, that field should be volatile; otherwise, the field should only be accessed 

via synchronization. Synchronization also causes flushing to main memory, so if a field is 

completely guarded by synchronized methods or blocks, it is not necessary to make it 

volatile.  

Any writes that a task makes will be visible to that task, so you don’t need to make a field 

volatile if it is only seen within a task.  

volatile doesn’t work when the value of a field depends on its previous value (such as 

incrementing a counter), nor does it work on fields whose values are constrained by the 

values of other fields, such as the lower and upper bound of a Range class which must 

obey the constraint lower <= upper.

 

It’s typically only safe to use volatile instead of synchronized if the class has only one 

mutable field. Again, your first choice should be to use the synchronized keyword—that’s 

the safest approach, and trying to do anything else is risky.  

What qualifies as an atomic operation? Assignment and returning the value in a field will 

usually be atomic.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值