Java - if语句是否是线程安全的?

时间:2014-04-10 18:35:16

标签: java multithreading thread-safety

这可能是一个愚蠢的问题但是......让我们假设我有一个类ContainerClass,如果包含一个HashSet,可以从几个添加的线程访问,也删除元素。其中一个线程,让我们称之为线程1,我执行以下代码:

if(ContainerClass.hashSet.containsKey(keyId))
    int number = ContainerClass.hashSet.get(keyId);

是否保证在第二行执行时,具有键keyId的元素仍然存在?或者这个线程可以在if语句中进行检查,然后暂停,然后另一个线程改变HashSet,并且线程1获得NullPointerException?

3 个答案:

答案 0 :(得分:5)

不,不能保证。

为了保证,您必须始终同步hashSet的访问权限(可能是java.util.HashMap),以防止其他线程在这些操作之间修改地图。

或者,有ConcurrentMap个实现,与java.util.HashSet不同,旨在供多个线程使用。它们支持一组额外的操作,例如putIfAbsent(),以便您可以自动检查并有条件地修改地图。

即使您简化代码以消除不必要的检查,在没有内存障碍的情况下跨线程共享java.util.HashMap仍然是不安全的。例如,如果另一个线程可能异步修改映射,则这不安全:

Integer tmp = ContainerClass.hashSet.get(keyId);
if (tmp != null) {
  int number = tmp.intValue();
}

答案 1 :(得分:0)

不保证,线程安全是指对象数据。如果多于1个线程可以同时修改它,那么它不是线程安全的。如果您担心在共享对象上执行逻辑,那么必须在锁定语句中执行逻辑(同步)。

答案 2 :(得分:0)

线程安全与共享的可变状态有关。

没有人可以从您的代码段中做出决定。如果是集体成员,你可能想要保护它。

如果它是局部变量,则它是线程安全的。

您还可以使用concurrent package

中的集合使其更安全