can throw more light on this ?
I'll try a different tack from that which Benji took. Maybe this will be too
low-level to help you, but it's the best I can do.
For a starter, imagine that the Java program is running on an 8-bit machine --
that's to say that the path to main memory ("bus") is 8-bits wide. (Such
machines may still exist, but you are unlikely to find yourself using one, this
is just the starting point for my example). Since the memory bus can only
carry 8 bits at a time, it will take 4 operations (at least) to write one
32-bit int to main store. So if you call:
setFoo(0x12345678);
then the underlying hardware will execute 4 separate updates of main memory.
The exact order is not important, but say it writes out:
0x12
0x34
0x56
0x78
to four consecutive 8-bit locations in main memory. That would effectively
copy the (32-bit) integer value into 32 bits of main memory. Now imagine that
a different thread on the same machine were attempting to perform:
setFoo(0xABABABAB);
If that happened at the same time as the other call to setFoo(), then -- unless
someone did something special to prevent it -- the resulting four writes of
0xAB could happen /arbitrarily/ interleaved with those of 0x12345667. So in
the end the main memory might hold:
0x 12 AB AB 78
The result is that from the point of view of the program, although we had only
ever called setFoo() with 0x12345678 and 0xABABABAB, a completely different
value could have ended up in the "foo" variable.
Things would be worse if foo was an object reference instead of a 32-bit int.
In that case, not only could we end up with a value of "foo" that had never
been supplied by setFoo(), but that value could actually be garbage. And if
that happened then the very /best/ result you could hope for is that your
program would crash immediately.
Now, this example has depended so far on the Java program running on ancient
hardware (or very constrained hardware). On more modern machines the bus is
32-bits wide, but the same sort of problem is still possible. That would
happen if the memory used to hold "foo" were not aligned on a 32-bit boundary
(very unlikely), or if the memory used to hold "x" (the parameter to setFoo())
was not held on a 32-bit boundary (possible). In such cases, the single 32-bit
value "x" cannot be transferred to main memory in a single 32-bit write. In
practise, on any /specific/ machine, there is a way to ensure that such
problems do not actually occur. And that is the point of the "atomic"
guarantee in the Java language definition. JVM implementations are /required/
to take whatever steps are necessary to ensure that such problems do not occur.
In a later post in this thread, you asked:
I'm still confused ! I don't have much experience in thread programing.
Best way, I guess would be to write a "proof of concept" program which
should indicate that this little piece of code is thread safe or not. I
would like to run this on all JVMs.
At least as far as this "atomic" issue is concerned, nobody can give you a code
snippet that shows the problem -- that's because no legal JVM is allowed to
/have/ a problem ;-)
On the other hand, as I mentioned, the "atomic" property (although very
valuable for correct programs) isn't itself enough -- not even nearly -- to be
able to write thread-safe programs. See my reply to Benji in this thread (a
few) for more details.
-- chris