Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java 101: Understanding Java threads, Part 2: Thread synchronization

Use synchronization to serialize thread access to critical code sections

  • Print
  • Feedback

Page 6 of 7

SynchronizationDemo2 demonstrates a synchronized instance method. However, you can also synchronize class methods. For example, the java.util.Calendar class declares a public static synchronized Locale [] getAvailableLocales() method. Because class methods have no concept of a this reference, from where does the class method acquire its lock? Class methods acquire their locks from class objects—each loaded class associates with a Class object, from which the loaded class's class methods obtain their locks. I refer to such locks as class locks.

Caution: Don't synchronize a thread object's run() method because situations arise where multiple threads need to execute run(). Because those threads attempt to synchronize on the same object, only one thread at a time can execute run(). As a result, each thread must wait for the previous thread to terminate before it can access run().

Some programs intermix synchronized instance methods and synchronized class methods. To help you understand what happens in programs where synchronized class methods call synchronized instance methods and vice-versa (via object references), keep the following two points in mind:

  1. Object locks and class locks do not relate to each other. They are different entities. You acquire and release each lock independently. A synchronized instance method calling a synchronized class method acquires both locks. First, the synchronized instance method acquires its object's object lock. Second, that method acquires the synchronized class method's class lock.
  2. Synchronized class methods can call an object's synchronized methods or use the object to lock a synchronized block. In that scenario, a thread initially acquires the synchronized class method's class lock and subsequently acquires the object's object lock. Hence, a synchronized class method calling a synchronized instance method also acquires two locks.

The following code fragment illustrates the second point:

class LockTypes
{
   // Object lock acquired just before execution passes into instanceMethod()
   synchronized void instanceMethod ()
   {
      // Object lock released as thread exits instanceMethod()
   }
   // Class lock acquired just before execution passes into classMethod()
   synchronized static void classMethod (LockTypes lt)
   {
      lt.instanceMethod ();
      // Object lock acquired just before critical code section executes
 
      synchronized (lt)
      {
         // Critical code section
         // Object lock released as thread exits critical code section
      }
      // Class lock released as thread exits classMethod() 
   }
}

The code fragment demonstrates synchronized class method classMethod() calling synchronized instance method instanceMethod(). By reading the comments, you see that classMethod() first acquires its class lock and then acquires the object lock associated with the LockTypes object that lt references.

Two problems with the synchronization mechanism

Despite its simplicity, developers often misuse Java's synchronization mechanism, which causes problems ranging from no synchronization to deadlock. This section examines these problems and provides a pair of recommendations for avoiding them.

  • Print
  • Feedback

Resources
  • Learn more about Java: See the complete listing for Jeff Friesen's Java 101 series -- archived on JavaWorld.
  • Also see the Java Tips series: More than five years of compiled tips from JavaWorld's expert readers.