Monday, June 24, 2013

To synchronize or not to synchronize?

Let us say we implement a very common functionality and offer our implementation as a open source library.  For example, we develop a library to keeping track of count of how many times a certain operation has taken place - like a call to web service.  We know this is very reusable.  But, we do not know how this functionality will be used by developers.  There could be many concerns on how this library could be used by the developers; but in this post, let us concentrate on: will the functionality be called from a multi-threaded environment?

The traditional way of handling multi-threading is to ensure make a critical-section is accessed in a single-threaded way.  To achieve this in Java, we use synchronized key word.  synchronized gets a lock (atomically) on the object (non-static methods) or class (static methods).  In Java, we also have an option of maintaining lock on an arbitrary object.  Code that is safe for execution by multiple threads is called thread-safe.

Now, the downside of synchronized is that it takes a lot of performance-hit.  For a fast program, it is advisable to use synchronized in as few places as possible - (a) this will reduce the performance-hit produced by synchronized (b) it ensures that as many threads executes in parallel as possible - both of which are good for performance.

So, given these facts about synchronized, in our Counter library, should we synchronize to make it thread-safe or not synchronize to make it fast?

The advisable approach is: do not synchronize unless you are sure that the code will be used in multi-threaded environment.

So, we would not make our Counter's methods synchronized.  If a developer intends to use our Counter class in a multi-threaded code, then the developer should ensure that the methods are called in a thread-safe manner.  This can be done by synchronizing over Counter object (or some other lock object) or by providing a wrapper method that is synchronized on the calling object.

Some simple multi-threading tips:

  • Always check if object is used in a multi-threaded environment.
  • Make the object immutable.  This means that you set values to an object's state only in constructor.  There should be no method accessible to other classes that can change the state of object after constructor has finished execution.
  • If you are dealing with a group of objects, use a separate lock object and synchronize based on that lock object.


No comments:

Post a Comment