Sunday, May 8, 2011

Thread Safety

The following Java API is known to be not thread safe.

SimpleDateFormat is not thread safe
The SimpleDateFormat implementation of DateFormat is not thread safe by design. If you wish to use this API you have several architectures to choose from in your application.
Use sychronization in your implementation - not advisable since this will queue your requests
Use InheritedThreadLocal storage by using get/set to use an instance of SimpleDateFormat per thread - recommended for environments running in thread pools - like in EE application servers.
Here we use an InheritedThreadLocal map entry to store an instance of the DateFormat object for each thread. See p.45 section 3.3 Thread confinement of "Java Concurrency in Practice" by Brian Goetz. Also, do not set this field before starting this thread or the ThreadLocal map value will be cleared to initialValue()
Use a pool of SimpleDateFormat instances - not in this case.

I will use the ThreadLocal map to store a unique instance for each thread of my running application. However, any ThreadLocal will not do - as I may be running in a pooled environment - like in an application server container like WebLogic, Tomcat, OC4J, WebSphere, JBoss, Spring tc, Spring dm, Geronimo and even JRun. In this case we need to use the subclass InheritableThreadLocal. When child threads are created, these threads will get a reference to their parent thread's ThreadLocal value by default. We will also want to override the InheritableThreadLocal.childValue() function to clone the parent value so that we are fully threads safe. Doing so will ensure thread safety whether ThreadLocal variables are set before or after thread creation.

private static final InheritableThreadLocal format = new InheritableThreadLocal() {
    @Override
    public DateFormat initialValue() {
      // This default value will get replaced by non-default constructors
      return new SimpleDateFormat(DefaultFormat);
    }
    @Override
    // All child threads must clone the formatter and not share the parent formatter by default
    protected DateFormat childValue(DateFormat parentValue) {
     // Object.clone() is a shallow copy, however DateFormat.clone() replicates mutable fields
        return (DateFormat) parentValue.clone();
    }

  };

SAXParser in JDOM SAXBuilder is not thread safe
The parser in SAXBuilder must be set to not be reused in your constructor.
See the following API
http://www.jdom.org/docs/apidocs/org/jdom/input/SAXBuilder.html#setReuseParser(boolean)

aBuilder = new SAXBuilder();
  aBuilder.setReuseParser(false);