Java HashTable size() 后跟 value() 在线程中安全吗?

标签 java multithreading thread-safety hashtable

我在一个线程中顺序执行以下内容:

int size = hashTable.size();

foreach.... in ... hasTable.values()

做某事

我的问题是 foreach 会被执行 size 次吗? (即使另一个线程同时放置/删除一个元素?

最佳答案

不,HashTable在方法级别上是线程安全的(多个线程可以随时调用任何方法),但不存在跨方法同步。在您的两条指令之间,其他线程可能会添加/删除甚至清除哈希表。

如果您需要保持这样的不变性,请制作一个防御性副本(不必是线程安全的)并在该副本上执行 size()/loop :

Map<K, V> map = null;
synchronized(hashTable) {
  map = new java.util.HashMap<>(hashTable);
}
map.size();
for(V v: map.values()) {
  //...
}

这里的 for-each 是安全的,并且保证运行 size 次。另外,如评论中所述,您可以在 hashTable 上同步:

synchronized(hashTable) {
  int size = hashTable.size();
  for(V v: hashTable.values()) {
    //...
  }
}

但是,这一解决方案意味着一次只有一个线程可以执行循环(如果循环需要一些时间才能完成,这可能会成为瓶颈)。通过防御性副本,每个线程都有自己的副本,并且多个线程可以同时循环。另一方面,如果 hashTable 非常大(复制成本昂贵)但迭代非常快,则此解决方案更好

关于Java HashTable size() 后跟 value() 在线程中安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12183291/

相关文章:

java - 在 Java 中发布和停止端点 Web 服务

java - eclipse 重绘编辑器屏幕(~= vi ctrl-L)

multithreading - 使用 3 个条件变量同步 3 个线程

c - linux下如何创建一个带超时的文件锁

c++ - 如果数据争用无关紧要,unordered_set线程安全吗?

java - 不明白这两个程序之间的区别,一个是 if-else 第二个是 if-else-if

java - 房间 : Not able to start activity adding the ID to the intent

java - 安排常规任务而不扩展TimerTask?

java - 多线程访问的静态方法,Java

c++ - 如何为多线程应用程序制作全局对象