Java代码:
public class IncreaseTest { public static int value = 0; public synchronized int increment() { return value++; } }
方法increment()是线程安全的吗?我是否必须添加修饰符关键字volatile,如下所示:
increment()
volatile
public static volatile int value = 0;
2wnc66cl1#
这段代码不是线程安全的。示例方法将在一个示例上同步,如果你有多个示例,它们将不会使用同一个监视器,因此更新可以交叉进行。您需要从value字段中删除static,或者向increment()方法中添加static。此外,由于您已将value设置为公共,因此存在另外一个问题,即可以在不使用同步的情况下在此方法之外更改或读取值,这可能导致阅读旧值。因此,将代码更改为以下代码将使其成为线程安全的:
value
public class IncreaseTest { private int value = 0; public synchronized int increment() { return value++; } }
cwxwcias2#
您可能应该使用atomicvars
2eafrhcq3#
如果您在两个线程中使用此方法,则确实需要volatile关键字。如果没有它,另一个线程可能无法获得最新值。(C#)
v9tzhpje4#
我不认为这是线程安全的,因为静态变量是公共的,可以被其他线程以非线程安全的方式访问。为了线程安全,你必须声明变量如下:
public static volatile int value;
现在value是volatile,将在synchronized块中访问。
4条答案
按热度按时间2wnc66cl1#
这段代码不是线程安全的。示例方法将在一个示例上同步,如果你有多个示例,它们将不会使用同一个监视器,因此更新可以交叉进行。
您需要从
value
字段中删除static,或者向increment()
方法中添加static。此外,由于您已将
value
设置为公共,因此存在另外一个问题,即可以在不使用同步的情况下在此方法之外更改或读取值,这可能导致阅读旧值。因此,将代码更改为以下代码将使其成为线程安全的:
cwxwcias2#
您可能应该使用atomicvars
2eafrhcq3#
如果您在两个线程中使用此方法,则确实需要volatile关键字。如果没有它,另一个线程可能无法获得最新值。(C#)
v9tzhpje4#
我不认为这是线程安全的,因为静态变量是公共的,可以被其他线程以非线程安全的方式访问。为了线程安全,你必须声明变量如下:
现在
value
是volatile,将在synchronized块中访问。