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

spa*_*ote 0 java multithreading thread-safety

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

if(ContainerClass.hashSet.containsKey(keyId))
    int number = ContainerClass.hashSet.get(keyId);
Run Code Online (Sandbox Code Playgroud)

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

eri*_*son 5

不,不保证.

为了保证它,你必须始终同步访问hashSet(可能是a java.util.HashMap),以防止另一个线程修改这些操作之间的映射.

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

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

Integer tmp = ContainerClass.hashSet.get(keyId);
if (tmp != null) {
  int number = tmp.intValue();
}
Run Code Online (Sandbox Code Playgroud)