Java News Brief        
                                          April 2000 Issue                                        

Headlines: 
Java Technical Insight of the Month   -  
Tips for creating thread-safe code
     Visit  The Java News Brief Archive for past issues of the JNB.
OCI Educational Services
       
                
Java Technical Insight of the Month
Tips for creating thread-safe code
(Avoiding Race Conditions)
By Eric Burke, Senior Software Engineer, Object Computing, Inc. (OCI)

Synopsis

Java has always included support for multi-threaded programming, in which more than one task executes concurrently. Two basic problems commonly occur in multi-threaded programs: This article focuses on a few simple programming techniques which you can adopt to minimize the possibility of race conditions.

When are Race Conditions an Issue?

Whenever a program utilizes multiple threads, deadlocks and race conditions are possible. Most programs do not have to concern themselves with these issues, but Java Servlets are a notable exception. With the rapid adoption of Servlet enabled web applications, many Java programmers are faced with threading issues for the first time.

Servlets are analogous to CGI scripts - they are Java programs which are used with a web server to create dynamic web applications. Each Servlet must be thread safe, because it may be asked to handle hundreds or thousands of client requests concurrently, each in a different thread.

Identifying Threading Problems

Race conditions are the most frequent threading problem. A simple example follows:
public class MyServlet extends HttpServlet {
    private Person currentUser = new Person();
    
    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        currentUser.setFirstName(req.getParameter("firstName"));
        currentUser.setLastName(req.getParameter("lastName"));

        // remainder of code omitted...this Servlet might perform some
        // operations on the currentUser object, such as storing the
        // data in a database...
    }
}
In this example, the doGet method is updating the currentUser object. Since this is a Servlet, the doGet method may be invoked by many threads concurrently. A thread that is in the middle of an invocation of doGet may be interrupted, and some other thread may overwrite the first and last name of the currentUser object.

This is an example of a shared resource being updated by multiple threads concurrently. In this case, the resource is a private field: currentUser. In other cases, the shared resource may be a flat file or a database connection.

Fixing the Problem

There are two general approaches. You can either make the shared resource thread safe, or you can ensure that no two threads ever update the resource concurrently. In this case, making individual methods in the Person class synchronized will not help, because you are making several independent method calls to the same currentUser object.

One naive approach is to make the entire doGet method synchronized. A synchronized method can only be executed by a single thread at a time, therefore this Servlet will only be able to handle one user at a time. All other users will be served one at a time, as each thread takes its turn executing the doGet method.

A better approach is to make the Person object local. Local variables are thread safe, because every thread gets a unique copy. The example would be changed to:

public class MyServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        Person currentUser = new Person();
        currentUser.setFirstName(req.getParameter("firstName"));
        currentUser.setFirstName(req.getParameter("lastName"));

        // remainder of code omitted...
    }
}
This code is now thread safe, and does not incur the same performance penalty as making the entire method synchronized.

Immutable Objects

An immutable object is one that cannot be modified after it has been constructed. These are guaranteed to be thread safe, because no two threads (or anybody!) can concurrently modify data in them. Constructors, by the way, are automatically thread safe, as well.
  // example immutable object
  public class Dog {
      private String name;
      private Date birthDate;
      
      public Dog(String name, Date birthDate) {
          this.name = name;
          this.birthDate = birthDate;
      }
      
      public String getName() {
          return name;
      }
      
      public Date getBirthDate() {
          // see note below!
          return (Date) birthDate.clone();
      }
  }
Creating immutable objects can be tricky. In the above example, the birthDate field can be modified, so we don't want to return a reference to it. Instead, clone the object and return a copy. This ensures that nobody can modify the Dog instance.

Immutable objects do not prevent you from changing data. You just have to replace the existing object with a new one that has your updated data. One simple approach is to use a manager object (which is thread safe) to create and replace immutable objects. For example:

// This class provides thread-safe methods to add/remove/update dogs.
// An actual implementation may use a relational database as its 
// underlying storage mechanism.
public class Kennel {
    public synchronized void create(Dog dog) { ... }
    public synchronized void update(Dog orig, Dog modified) { ... }
    public synchronized void delete(Dog victim) { ... }
    public synchronized Dog find(String name) { ... }
    ...other methods
}
Although the Dog itself cannot be modified, you can obtain an existing object and replace it with a new one by using the update(...) method in Kennel.

Summary

Some general strategies for making objects thread safe include:

Future Research

Java 2 (aka JDK 1.2) adds a new class called ThreadLocal, which makes it easy to create and use variables which are local to a given thread. If these variables are not shared with multiple threads, then it follows that they are thread safe.


OCI Educational Services               

OCI has one of the most comprehensive OO training curriculums in the country.  Clients contract group training that is either taught at the client site or at an OCI Education Center in Tempe, AZ or St. Louis, MO.  We encourage you to check our our Object-Oriented Technology Curriculum show below:   (click on course titles for online descriptions)  

C ProgrammingJava Syntax for Non-C ProgrammersIntroduction to JavaObject-Oriented Analysis and DesignObject-Oriented ConceptsIntroduction to C++ for Non-C ProgrammersObject-Oriented Programming and C++Java ProgrammingDeveloping Graphical User Interfaces using JavaJavaBeans ProgrammingAdvanced Java ProgrammingCORBA ProgrammingIntroduction to CORBAData Structures and Programming Techniques in C/C++TAO's Implementation of CORBASelected Topics in Object-Oriented Programming Using the ADAPTIVE Communication Environment C++ FrameworkAdvanced C++Developing Microsoft Windows Applications in Visual C++ and MFC

For more information or to register, email training.


Object Computing, Inc. is a Sun Authorized Java Center in St. Louis and a Member of the Object Management Group, OMG.  OCI specializes in distributed computing using object-oriented and web-enabled technologies and provides Consulting, Education, and Product Development services to clients nation-wide.  For more information contact us at 314-579-0066, 480-752-0042 (Tempe) or email info.

For Information on Employment Opportunities
Click here OCI CAREER OPPORTUNITIES
or call 1-888-962-4624 
or email hr


The Java News Brief is a monthly newsletter.  The purpose and intent of this publication is to advance Java, provide technical value, and to announce available OCI Java services.  If you would prefer to not receive this newsletter or would like to subscribe please email JNB and enter SUBSCRIBE or UNSUBSCRIBE within the Subject line.

Copyright (c) 2000.  Object Computing, Inc.   All rights reserved.   Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.  Object Computing, Inc. is independent of Sun Microsystems, Inc.