Every Java object created, including every Class loaded, has an associated lock or monitor. Putting code inside a synchronized block makes the compiler append instructions to acquire the lock on the specified object before executing the code, and release it afterwards (either because the code finishes normally or abnormally). Between acquiring the lock and releasing it, a thread is said to "own" the lock. At the point of Thread A wanting to acquire the lock, if Thread B already owns the it, then Thread A must wait for Thread B to release it. Thus in the example below, simultaneous calls to increment() and getCount() will always behave as expected; a read could not "step in" while another thread was in the middle of incrementing.
public class Counter {
private int count = 0;
public void increment() {
synchronized (this) {
count++;
}
}
public int getCount() {
synchronized (this) {
return count;
}
}
}
Synchronizing also performs another important– and often overlooked– function. Unless told otherwise (using a synchronized block or via the volatile keyword– see below), threads may work on locally cached copies of variables such as count, updating the "main" copy when it suits them. For the reasons discussed in our overview of processor architecture, they may also re-order reads and writes, meaning that updating a variable may not mean that it is updated when otherwise expected. However, on entry to and exit from blocks synchronizeded on a particular object, the entering/exiting thread also effectively synchronizes copies of all variables with main memory1.
The next page deals with some of the gorier details of this synchronization of variables with main memory. Or you may prefer to skip it and go on to the following page which detals with methods declared as synchronized.
1. We'll discuss in a moment what that actually means, but fundamentally, locally cached copes if variables must be 'flushed' to main memory on exit, and accesses to variables accessed inside the synchronized block cannot be re-ordered to occur outisde the synchronized block.
Written by Neil Coffey. Copyright © Javamex UK 2008. All rights reserved.