Java Multithreading Issue – Partially populated objects

Overview

This document highlights one of the most common multi-threading problem in java applications.

There is a very common use-case where one thread (t1) creates and populates the object whereas another thread (t2) tries to access it at the same time. To avoid synchronized block which supposedly might impact performance, programmers put in null check so that second thread (t2) uses object only when it’s created.

 

Example

In below code snippet, Date object is created in the initialize method and stored at the class level whereas it’s accessed in getTimeInMillis method.  

To avoid the possibility of a thread accessing the date object before it’s initialized, programmers usually put a null check so that there is no null pointer exception and also date object is used only where it’s initialized. 

Code

 1 public class DateHolder { 2 3   private Date date; 4 5   public void initialize() { 6 7       date = new Date();   8       Calendar calendar = new GregorianCalendar(); 9       calendar.set(2015, 05, 01); 10      date.setTime(calendar.getTimeInMillis()); 11  } 12 13  public long getTimeInMillis() { 14 15      if(date != null) { 16         return date.getTime(); 17      } 18      return 0; 19  }   }

 

There is a hidden issue in this approach which gets overlooked. If initialized and getTimeInMillis methods are called at same time, date object created at line 7 (which is not fully populated yet) might get used by thread 2 at line number 16 causing wrong value to be returned. In this example, thread 2 would return current time back instead of time corresponding to 2015/05/01. 

 

Solution

There can be multiple solutions to this problem but the simplest and straight forward would be to surround it in synchronized block so that thread 2 waits for object to be created and fully populated before it’s used. 

{jcomments on} 

 


Leave a Reply

Your email address will not be published. Required fields are marked *