Interview Question:
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++; } } |
This post explains a general interview question that has been asked by Google and a lot of companies. It’s low-level and not about how to design concurrent program.
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.
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.
Nice