作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在一个线程中顺序执行以下内容:
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/
我是一名优秀的程序员,十分优秀!