如何使 Java 中的方法线程安全?
原文地址:http://www.programcreek.com/2014/02/how-to-make-a-method-thread-safe-in-java/
一个面试问题:
以下方法线程安全吗? 如何使它线程安全?
class MyCounter {
private static int counter = 0;
public static int getCount() {
return counter++;
}
}
这是 Google 和许多其他公司经常提出的一个的面试问题。
首先,答案是否定的,该方法不是线程安全的,因为计数器累加操作不是原子性的,这意味着它包含多个原子操作。 在这种情况下,一个是访问该值,另一个是将值增加 1。

当线程 1 在 t1 访问方法时,线程 2 可能还没执行完该方法。 所以返回给线程 1 的值是没有增加的值。
使方法线程安全 - 方法 1
添加 synchronized 关键字到此方法将使其线程安全。 当 synchronized 被添加到静态方法时,Class 对象将被锁定。
标记一下就能实现同步? 答案是肯定的。
class MyCounter {
private static int counter = 0;
public static synchronized int getCount() {
return counter++;
}
}
如果该方法不是静态的,那么添加 synchronized 关键字将同步类的实例,而不是 Class 对象。
使方法线程安全 - 方法 2
在下面这个例子中,我们通过使用 java.util.concurrent.atomic 包中的 AtomicInteger 来创建 count++ 原子。
import java.util.concurrent.atomic.AtomicInteger;
public class MyCounter {
private static AtomicInteger counter = new AtomicInteger(0);
public static int getCount() {
return counter.getAndIncrement();
}
}
关于线程安全的一些有用的常识
局部变量在 Java 中是线程安全的。
每个线程都有自己的堆栈,两个不同的线程不会共用同一个堆栈。 在方法中定义的所有局部变量将被分配给堆栈内存,当前线程一旦执行完该方法,堆栈帧将被删除。