Monday, 26 December 2016

How to make a method thread-safe in Java?

Is the following method thread-safe? How to make it thread-safe?

class MyCounter {
private static int counter = 0;

public static int getCount() {
return counter++;
}
}


First of all, the answer is NO. The method is not thread-safe, because the counter++ operation is not atomic, which means it consists more than one atomic operations. In this case, one is accessing value and the other is increasing the value by one.

How to make a method thread-safe in Java?

When Thread 1 accesses the method at t1, Thread 2 may not be done with the method. So the value returned to Thread 1 is the value that has not been increased.

Make a method thread-safe - Method 1

Adding synchronized to this method will makes it thread-safe. When synchronized is added to a static method, the Class object is the object which is locked.

Is marking it synchronized enough? The answer is YES.

class MyCounter {
private static int counter = 0;

public static synchronized int getCount() {
return counter++;
}
}
If the method is not static, then adding synchronized keyword willsynchronize the instance of the class, not the Class object.

Make a method thread-safe - Method 2

In this particular counter example, we actually can make count++ atomic by using AtomicInteger from the package "java.util.concurrent.atomic".

import java.util.concurrent.atomic.AtomicInteger;

public class MyCounter {
private static AtomicInteger counter = new AtomicInteger(0);

public static int getCount() {
return counter.getAndIncrement();
}
}

Some other useful facts about thread-safe

Local variables are thread safe in Java.

Each thread has its own stack. Two different threads never shares the same stack. All local variables defined in a method will be allocated memory in stack. As soon as method execution is completed by the current thread, stack frame will be removed.