Java代码:
public class IncreaseTest {
public static int value = 0;
public synchronized int increment() {
return value++;
}
}
方法increment()
是否是线程安全的?我是否必须按如下方式添加修饰符关键字volatile
:
public static volatile int value = 0;
答案 0 :(得分:21)
此代码不是线程安全的。实例方法将在实例上同步,如果您有多个实例,它们将不使用相同的监视器,因此更新可以交错。
您需要从value
字段中移除静态或向increment()
方法添加静态。
此外,正如您已将value
公开,还有一个问题是,如果不使用可能导致读取旧值的同步,则可以在此方法之外更改或读取值。
因此,将代码更改为以下代码将使其成为线程安全的:
public class IncreaseTest {
private int value = 0;
public synchronized int increment() {
return value++;
}
}
答案 1 :(得分:1)
我不认为这是线程安全的,因为静态变量是公共的,并且可以由其他线程以非线程安全的方式访问。为了保证线程安全,您必须按如下方式声明变量:
public static volatile int value;
现在value
是易失性的,将在同步块中访问。
答案 2 :(得分:1)
您应该使用atomicvars
答案 3 :(得分:0)
如果您在两个线程中使用此方法,则需要使用volatile关键字。没有它,另一个线程可能无法获得最新值。 (C#)