I am little confused...
Is it true that reading\writing from several threads all except long and double are atomic operations and it's need to use volatile only with long and double?
It sounds like you're referring to this section of the JLS. It is guaranteed for all primitive types -- except double
and long
-- that all threads will see some value that was actually written to that variable. (With double
and long
, the first four bytes might have been written by one thread, and the last four bytes by another thread, as specified in that section of the JLS.) But they won't necessarily see the same value at the same time unless the variable is marked volatile
.
Even using volatile
, x += 3
is not atomic, because it's x = x + 3
, which does a read and a write, and there might be writes to x
between the read and the write. That's why we have things like AtomicInteger
and the other utilities in java.util.concurrent
.
Let's not confuse atomic with thread-safe. Long and double writes are not atomic underneath because each is two separate 32 bit stores. Storing and loading non long/double fields are perfectly atomic assuming they are not a compound writes (i++
for example).
By atomic I mean you will not read some garbled object as a result of many threads writing different objects to the same field.
From Java Concurrency In Practice 3.1.2
Out-of-thin-aire safety: When a thread reads a variable without synchronization, it may see a stale value, but at least it sees a value that was actually placed there by some thread rather than some random value. This is true for all variables, except 64-bit long and double, which are not volatile. The JVM is permitted to treat 64-bit read or write as two seperate 32-bit operations which are not atomic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With