Never synchronize on Java boxed primitives

This is another pitfall that can easily compromise a whole application if not understood, it involves thread safety, Java objects immutability and boxed primitives.
Standard Java classes like Integer and Long are immutable. A class is said to be immutable if it is implemented in such a way that it’s value cannot be changed once the class has been instantiated.

Integer value = 10;

The Integer object declared above is immutable, it’s value can not be changed.
But wait a second, you say, what if I do this?

value++;

Oh, I say, you changed the object’s value with the increment operator!
Actually this is not what happened, when it comes to running this code the statement above is pretty much equivalent to this one:

value = new Integer(value + 1);

Since this class is immutable, as soon as you change it’s value a new Integer instance with the new value is created and assigned to value. This is what we call immutability and applies also to String, Boolean, Long, Double, BigInteger and so on. This is the first step in understanding what follows.
The second step is understanding boxed primitives, but you may already know what they are.

Boxed primitives can be really useful sometimes, and can be very tricky too. You can use them to represent values such as Integer, Long, Boolean, Double and so on. They are called boxed primitives, or wrapped primitives, because they wrap a primitive Java type such as int and long inside a class allowing a more flexible approach to a strong object oriented environment such as Java.

If you work in a multi threading environment you’ll often need to synchronize parts of your code to make sure that no thread except yours operates on an object that you are working on. Let’s say you have an Integer value that can be incremented by one thread and decremented by another thread, your code may look like this:

private Integer value = 0;
...
synchronized(value) {
  ...				
  value++;
  ...
}

But this innocent looking piece of code hides an horrible monster, can you spot it?
The synchronized block is synchronized against the value object which will no more be itself as soon as we increment it, let’s see it under a different light using what we learned about immutability:

private Integer value = 0;
...
synchronized(value) {
  ...				
  value = new Integer(value + 1);
  ...
}

The synchronized block works by locking the object on which we want to synchronize, but the object will change inside the block! The value reference will point to another Integer object after the increment!
The new Integer object with value 11 won’t be locked and as a result if some other thread tries to synchronize on the value object after our increment operation it will succeed.
As a result we’ll have two or more threads running at the same time even if they are supposed to be waiting to execute critical code sections one at a time.
This is dangerous as hell, this is the kind of bug that starts showing up on release day..

Advertisements

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