在Collections javadoc中,它被提及如下..
当迭代任何集合视图时,用户必须手动同步返回的地图:
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized (m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
我的问题是,如果我宣布了Hashtable,我可以在不同步的情况下使用它。 如下所示
Hashtable ht = new Hashtable();
Set s = m.keySet();
Iterator i = s.iterator();
while (i.hasNext())
foo(i.next());
答案 0 :(得分:3)
是
由所有类"集合视图方法"返回的集合的迭代器方法返回的迭代器。 fail-fast :如果在创建迭代器之后的任何时候对Hashtable进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出{{3 }}。
所以,如果你想要通过Hashtable
的迭代器,你必须确保没有其他人同时修改Hashtable
对象。如果该对象在多个线程之间共享,那么最好的方法是在公共对象上进行同步,例如您迭代的Hashtable
。{/ p>
答案 1 :(得分:3)
如果我声明了Hashtable,我可以在不同步的情况下使用它。
您可以,但如果您想避免ConcurrentModificationException,则不应该。即它使用同步就像同步的HashMap一样具有相同的限制。
注意:如果你使用ConcurrentHashMap,你不需要锁定它(事实上你不能)
答案 2 :(得分:1)
如果我声明了Hashtable并且可以在不同步的情况下使用它吗?
不,你需要同步它。
原因:
对Java中[任何]集合的迭代不是线程安全的。
这是Hashtable#keyset()方法的实现:
public Set<K> keySet() {
if (keySet == null)
keySet = Collections.synchronizedSet(new KeySet(), this);
return keySet;
}
如果你注意到,它会返回synchronizedSet。正如它在javadoc It is imperative that the user manually synchronize on the returned set when iterating over it
中提到的那样,因为SyncronizedSet中的iterator
方法未同步。
答案 3 :(得分:0)
当您在单个线程中执行每个操作时,在这种情况下不应该观察到并发问题。虽然我必须说你从JavaDoc提供的示例与示例无关,但您有疑问。请更详细地修改问题。