是否从Collections.unmodifiableMap Fail-Fast返回映射。
换句话说,如果其他人使用地图的“可修改视图”修改地图,是否会抛出concurrentModificationException和iterating
发布于 2012-03-12 17:59:05
由于API没有定义行为,因此它是依赖于实现的,也就是说,它可以根据您使用的Java运行时而变化。
对于Sun Java6运行时,看起来似乎行为将从您包装的Map继承。这是明智的行为,尽管如我所说,不能保证跨实现。
编辑- Sun Java6的测试用例:
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class TestUnmod {
public static void main(String[] args) {
Map<String,String> map = new HashMap();
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
Map<String,String> unmod = Collections.unmodifiableMap(map);
Iterator<String> it = unmod.values().iterator();
System.out.println(it.next());
map.put("d", "d");
System.out.println(it.next());
}
}输出:
b
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
at java.util.HashMap$ValueIterator.next(HashMap.java:822)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
at TestUnmod.main(TestUnmod.java:18)发布于 2012-03-12 17:53:52
不,它们不是快速失败的。
尽管没有特别提到,但API文档指出,“对返回的映射进行查询操作”读取到“指定的映射,并尝试修改返回的映射...,将导致UnsupportedOperationException”。由于不可修改的map仅委托给原始map,因此有关使用原始map的所有限制也与不可修改的包装器相关。
发布于 2012-03-12 17:57:45
下面是一个更新的示例,它显示了异常被抛出(感谢@jarnbjo):
final Map<Integer, String> original = new HashMap<Integer, String>();
final int capacity = 1000 * 100;
for (int i = 0; i < capacity; i++) {
original.put(i, UUID.randomUUID().toString());
}
final Map<Integer, String> unmodifiable = Collections.unmodifiableMap(original);
ExecutorService executor = Executors.newFixedThreadPool(2);
for (int k = 0; k < 5; k++) {
executor.execute(new Runnable() {
@Override
public void run() {
Random r = new Random();
int c = original.size();
for (int i = c; i < c + 1000; i++) {
original.put(i, UUID.randomUUID().toString());
}
}
});
executor.execute(new Runnable() {
@Override
public void run() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<Integer, String> entry : unmodifiable.entrySet()) {
sb.append(entry.getValue()).append(' ');
}
System.out.println("sb.toString().length() = " + sb.toString().length());
}
});
}https://stackoverflow.com/questions/9664709
复制相似问题