|
|
Threads - Thread Locking Protocols
| Note |
- This information is not required for the Certification exam. I've included it because I found it useful in helping me to understand how thread locks or monitors actually worked.
|
- each program has an area of main memory where it stores it's classes, arrays and variables
- the main memory has a master copy of every variable and contains one lock for each object
- this main memory area is accessible by all the programs threads
- threads can only communicate thru the shared main memory
- each thread has a working memory where it keeps copies of the values of variables it uses or assigns
- to access a shared variable, a thread obtains a lock and flushes its working memory, guaranteeing the shared value will be loaded from main memory
- as a thread executes, it operates on its working copies
- when a synchronized block or method is entered, actions by the thread and main memory must occur in a specific order
- the thread obtains a lock on the object and flushes its working copy of the object
- main memory reads the objects value from it's master copy
- the thread loads the value passed by the main memorys read operation
- the thread uses it's working copy of the object, passing it to it's excuatable engine
- the thread assigns the resulting value back to it's working copy
- the thread stores the new value, passing it back to main memory
- main memory writes the value passed by the threads store action back to the master copy
- the thread releases it's lock on the object
- every read action by main memory must be followed by a load action in the thread
- every store action in the thread must be followed by a write action in main memory
- the read and write actions in main must be executed in the order they were performed in the thread
- every use action in a thread must be followed by an assign action however an assign does not necessarily have to be proceeded by a use
- all use and assign actions must occur in the order dictated by the threads executable code
- assign must follow a load before a store can occur or another load can occur
- every lock action by a thread MUST be paired with an unlock
- as Java allows re-entrant locks, a thread may obtain multiple locks which must be paired with matching unlocks
- only one thread at a time can hold a lock on an object
- a thread is not permitted to unlock a lock it doesn't own
- a thread can only release it's lock after it has performed a store
Special case: double and long variables
- double and long variables are handled as two 32-bit variables
- if the variables are not declared volatile and if they are being used by two or more threads the final result may be a combination of both thread actions
volatile
- declaring a thread volatile prevents the compiler from optimizing and in-lining the code; forcing the thread to reread the value every time the variable is accessed
int value = 5;
for(;;) {
display.showValue(value);
Thread.sleep(1000); // wait one second
}
- in the above example, value is assigned a literal, under normal conditions, if display.showValue() does not make any changes to value the compiler would in-line the code, assuming value will not be changed while the method is running
- however, if you have other threads that can change value then you should declare it as volatile
- this will stop the compiler from in-lining the code and force the value to be reread each time the loop iterates
|