Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are 64 bit assignments in Java atomic on a 32 bit machine?

If I have code like this -

long x; x  = 0xFFFFFFFFL; 


If i run this code on a 32 bit machine is it guaranteed to be atomic or is it possible that a different thread reading x, might get an incomplete/garbage value?

like image 543
pdeva Avatar asked Aug 11 '10 23:08

pdeva


People also ask

Is Java INT 32 or 64-bit?

int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -231 and a maximum value of 231-1.

Will the size of primitive data types change if OS is changed from 32-bit to 64-bit in Java?

Yes, the sizes are the same on both 32-bit and 64-bit JVM.

Why long and double are not atomic in Java?

It's not atomic because it's a multiple-step operation at the machine code level. That is, longs and doubles are longer than the processor's word length.


2 Answers

Here is the short summary:

  • For references, reads/writes are ALWAYS atomic (even in 64 bit implementations!)
  • For int, char, byte, short, boolean, float, reads/writes are ALWAYS atomic
  • For double and long, if they're volatile, reads/writes are ALWAYS atomic

Therefore there is only exception where reads/writes may not be atomic:

  • For double and long, if they're NOT declared volatile, they're NOT GUARANTEED to be atomic

So as far as atomicity of reading/writing shared data is concerned, you only need to make volatile any double or long. Everything else is already guaranteed to be atomic, regardless of how many bits are used in actual implementation.


On the specification

Here's the relevant section reproduced here for quick reference:

JLS 17.7 Non-atomic Treatment of double and long

Some implementations may find it convenient to divide a single write action on a 64-bit long or double value into two write actions on adjacent 32 bit values. For efficiency's sake, this behavior is implementation specific; Java virtual machines are free to perform writes to long and double values atomically or in two parts.

For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64 bit value from one write, and the second 32 bits from another write. Writes and reads of volatile long and double values are always atomic. Writes to and reads of references are always atomic, regardless of whether they are implemented as 32 or 64 bit values.

VM implementors are encouraged to avoid splitting their 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as volatile or synchronize their programs correctly to avoid possible complications.

See also

  • JLS 17.6 Word Tearing - guarantees e.g. a byte can be updated without neighbor interference
  • JLS 8.3.1.4 volatile Fields
  • Java Tutorials/Essential Classes/Concurrency/Atomic Variables
    • Note that given int i;, i++ is NOT atomic!

Related questions

  • Is there any point in using a volatile long?
  • How to declare array elements volatile in Java?
    • A volatile long[] is volatile reference to an array of long
    • The long elements themselves are not volatile
like image 196
polygenelubricants Avatar answered Sep 20 '22 21:09

polygenelubricants


No they are not. A 64 bit store is treated as two separate 32 bit stores. So in a concurrent environment that variable can have the high 32 of one write and the low 32 of another write, obviously not thread safe.

like image 29
John Vint Avatar answered Sep 21 '22 21:09

John Vint