for*_*ill 0 java multithreading hashtable thread-safety
我在一个线程中按顺序执行以下操作:
int size = hashTable.size();
foreach .... in ... hasTable.values()
做一点事
我的问题是foreach会执行大小的时间吗?(即使另一个线程同时放置/删除元素?
不,HashTable在方法级别是线程安全的(多个线程可以随时调用任何方法)但是没有跨方法同步.在您的两条指令之间,其他线程可能会添加/删除甚至清除哈希表.
如果你需要保持这样的不变量,做一个防御性的副本(不必是线程安全的)并size()在该副本上执行/循环:
Map<K, V> map = null;
synchronized(hashTable) {
map = new java.util.HashMap<>(hashTable);
}
map.size();
for(V v: map.values()) {
//...
}
Run Code Online (Sandbox Code Playgroud)
这里for-each是安全的,并且保证运行大小 - 次.同样如评论中所述,您可以同步hashTable:
synchronized(hashTable) {
int size = hashTable.size();
for(V v: hashTable.values()) {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这个解决方案意味着一次只有一个线程可以执行循环(如果你的循环需要一些时间来完成,这可能会成为一个瓶颈).使用防御性副本,每个线程都有自己的副本,并且几个线程可以同时循环.另一方面,如果这个解决方案非常大(复制起来很昂贵),那么这个解决方案会更好,hashTable但迭代速度非常快.