Friday, 7 August 2009

Threadlocal

I ran into an interesting problem last week concerning Threadlocal. This is a class in Java. The details are here. You save something in a ThreadLocal class, usually held somewhere static, and any calls to fetch it out from the same thread will get the same value out again. You get the benefits of a static while staying thread safe.

This is really useful, but there are dangers, specifically there are problems with side effects. One of these I am about to describe.

Okay, we're about to commit using Hibernate. One of the fields in the Hibernate object maps to an object. Hibernate calls the object's method during the commit (I forget which method, probably serialize) and that method tries to get a configuration object from ThreadLocal. If it fails to get the configuration it instantiates one and carries on, loading the resulting configuration object into the ThreadLocal.

At this point bad things happen. That configuration object needs certain values and the default configuration does not do the job. We must have the configuration object loaded by something else and never by default.

This is an example of a side effect. Deliberate side effects can be good things. This one was not. It took a lot of time to figure out what was going on. We had no knowledge of the ThreadLocal. This was not our code, I won't embarrass the open source project it belongs to, but it would have been a lot better if an exception had been thrown if the configuration object was missing. We would have known what the problem was over a week ago.

So if you use ThreadLocals, or even statics, make sure you are really, really careful how they are initialised. You probably want to have them initialised in just one place using one mechanism.
Post a Comment