Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Achieve strong performance with threads, Part 2

Use synchronization to serialize thread access to critical code sections

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Is creating multithreaded Java programs hard? With the information gleaned from Part 1 of Java 101's thread series only, you might answer no. After all, last month I showed you how easy it is to create thread objects, start threads that associate with those objects by calling Thread's start() method, and perform simple thread operations by calling other Thread methods, such as the three overloaded join() methods. Yet many developers face difficulty when developing properly behaving multithreaded programs. All too often, their programs function erratically or produce erroneous values. For example, a multithreaded program might store incorrect employee details, such as name and address, in a database. The name might belong to one employee, whereas the address belongs to another. What causes that strange behavior? The lack of synchronization: the act of serializing, or ordering one at a time, thread access to those code sequences that let multiple threads manipulate class and instance field variables, and other shared resources. I call those code sequences critical code sections.

Note
Unlike class and instance field variables, threads cannot share local variables and parameters. The reason: Local variables and parameters allocate on a thread's method-call stack. As a result, each thread receives its own copy of those variables. In contrast, threads can share class fields and instance fields because those variables do not allocate on a thread's method-call stack. Instead, they allocate in shared heap memory—as part of classes (class fields) or objects (instance fields).


This article, the second in a four-part series that explores threads, teaches you how to use synchronization to serialize thread access to critical code sections. I begin with an example that illustrates why some multithreaded programs must use synchronization. I next explore Java's synchronization mechanism in terms of monitors and locks, and the synchronized keyword. Because incorrectly using the synchronization mechanism negates its benefits, I conclude by investigating two problems that result from such misuse.

Read the whole series on thread programming:



The need for synchronization

Why do we need synchronization? For an answer, consider this example: You write a Java program that uses a pair of threads to simulate withdrawal/deposit of financial transactions. In that program, one thread performs deposits while the other performs withdrawals. Each thread manipulates a pair of shared variables, class and instance field variables, that identifies the financial transaction's name and amount. For a correct financial transaction, each thread must finish assigning values to the name and amount variables (and print those values, to simulate saving the transaction) before the other thread starts assigning values to name and amount (and also printing those values). After some work, you end up with source code that resembles Listing 1:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources