这可能是一个愚蠢的问题但是......让我们假设我有一个类ContainerClass,如果包含一个HashSet,可以从几个添加的线程访问,也删除元素。其中一个线程,让我们称之为线程1,我执行以下代码:
if(ContainerClass.hashSet.containsKey(keyId))
int number = ContainerClass.hashSet.get(keyId);
是否保证在第二行执行时,具有键keyId的元素仍然存在?或者这个线程可以在if语句中进行检查,然后暂停,然后另一个线程改变HashSet,并且线程1获得NullPointerException?
答案 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
中的集合使其更安全