Thread Safety – Race Condition

When only considering operation atomicity and memory visibility, the following code is thread safe.  But a potential race condition can lead to bugs that are hard to debug. The race condition may seem obvious here, but this faulty code is quite possible to survive the unit test and code review in real complicated environment.


public class ObserverExample
{
 private final ConcurrentHashMap<Event, Response> eventsAndResponses = new ConcurrentHashMap<>();

public void onSignal1(Event event, Response response)
 {
 eventsAndResponses.putIfAbsent(event, response);

...
 }

public void onSignal2(Event event)
 {
 Response response = eventsAndResponses.get(event);
response.get();

...
 }
}

The snippet above is very common when coding with Observer or State pattern. Its problem of race condition comes from unpredictable invocation sequence of onSignal1 and onSignal2 in multi-threading environment, so you can get a null response if onSignal2 is invoked later.

One way to eliminate the race condition here is to guarantee the invocation sequence of these methods (not discussed in this post). The other way is to make the ObserverExample class itself immune to such problem by by confining each thread’s variables (as seen below) to reduce cross-talk, or even make the class immutable.


public class ObserverExample
{
public void onSignal1(Event event, Response response)
{
...
}

public void onSignal2(Event event, Response response)
{
response.get();

...
}
}

Advertisements
This entry was posted in Java, Programming and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s