For instance, if you are iterating something on a boolean field ( while(! stop) ) until another thread changes it, the compiler doesn't know or see that and unless the boolean field is volatile, it might make an optimization on the assumption that the value of boolean is never going to change, so it eventually transforms it into an infinite loop. If it is a volatile field the compiler knows that it is not allowed to do such an operation.
What is important to be aware of !!!
Knowing that processes use separate address spaces and all threads share one is irrelevant here. In Java Memory Model, memory that can be shared between threads is called shared memory or heap memory. All instance fields, static fields and array elements are stored in heap memory. Local variables are never shared between threads and are unaffected by the memory model.
The most important thing is visibility of JVM inter-thread actions. Inter-thread action is an action performed by one thread that can be detected or influenced by another one (read & write volatile/non-volatile; locking & unlocking a monitor, actions when thread starts/terminates and some external actions).
Visibility and so called happens before relationship differ for synchronization / locking and using volatile field modifier.
Blocking synchronization using Locks or synchronized methods / statements :
- thread A acquires a lock on an object and do some writes
- the Lock release pushes out the updates that thread 1 made to shared memory
- thread B performs subsequent Lock acquire that grabs the updates that were performed by thread A by updating the cached values of fields from shared memory.
- thread B performs read or write on updated values
When you are using non blocking synchronization - using volatile field modifier, you practically perform so called happens-before relationship manually.
- threads A, B, C change some field(s) (write) in the flow of their execution and perform a write to a volatile field
- each other thread that performs a read on that volatile field will see values of those changed fields updated in shared memory up until any of threads A, B, C wrote to it
JSR-133 is the overall thread and Java Memory Model specification. JSR-166 relates to the utilities in java.util.concurrent package.
I think that Java concurrency is for human beings. And after all I like it. There is other stuff that is quite inedible in comparison with Java concurrency, like practically useless java.lang.reflect.Type that looks it might come handy but finally you have to code all by yourself to get what you need from it :-)
No comments:
Post a Comment