ConcurrentHashMap、CopyOnWriteArrayList 能在多线程条件下绝对安全么?
可以处理以下几种情况么?在不加额外的同步块情况下。
// put-if-absent idiom -- contains a race condition
// may require external synchronization
if (!map.containsKey(key))
map.put(key, value);
// ad-hoc iteration -- contains race conditions
// may require external synchronization
for (int i=0; i<list.size(); i++) {
doSomething(list.get(i));
}
// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
doSomething(i.next());
}
可以处理以下几种情况么?在不加额外的同步块情况下。
// put-if-absent idiom -- contains a race condition
// may require external synchronization
if (!map.containsKey(key))
map.put(key, value);
// ad-hoc iteration -- contains race conditions
// may require external synchronization
for (int i=0; i<list.size(); i++) {
doSomething(list.get(i));
}
// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
doSomething(i.next());
}
解决方案 »
- 一道面试题,求更好的答案
- 面试基础题一(如果觉得自己知识掌握牢固了,去面试吧!)
- 求救java swing做的记事本设置不了默认字体大小有时候退出还会报错
- 强烈建议,JDK的帮助文件里应该写用法的例子.....大家讨论下
- 简单的问题
- 下面内容我不太理解,哪位大侠能否举例说明一下
- 声音播放中止的判断
- 紧急求助!!!JNI调用vc编写的dll,在javah生成的.h对应的.cpp中如何定义全局变量??
- 新人请教,用Swing的JPanel画图后,为什么不会刷新?
- 关于JDBC, 请哪位大侠帮忙告诉我完整的JDBC的联结方式
- 一个解密的问题,对数据敏感的人来看看吧
- readObject时 java.io.StreamCorruptedException: invalid type code: 6A?有时候却又没问题。
支持检索的完全并发和更新的所期望可调整并发的哈希表。此类遵守与 Hashtable 相同的功能规范,并且包括对应于 Hashtable 的每个方法的方法版本。不过,尽管所有操作都是线程安全的,但检索操作不 必锁定,并且不 支持以某种
防止所有访问的方式锁定整个表。此类可以通过程序完全与 Hashtable 进行互操作,这取决于其线程安全,而与其同
步细节无关。 CopyOnWriteArrayList:
ArrayList 的一个线程安全的变体,其中所有可变操作(添加、设置,等等)都是通过对基础数组进行一次新的复制来
实现的。这一般需要很大的开销,但是当遍历操作的数量大大超过可变操作的数量时,这种方法可能比其他替代方法更
有效。在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时,它也很有用。
虽然ConcurrentHashMap是线程安全的,看看下面一段代码:ConcurrentHashMap<String,String> map;
String getString(String name) { String x = map.get(name); if (x == null) { x = new String(); map.put(name, x); } return x;
}如果你只调用get(),或只调用put()时,ConcurrentHashMap是线程安全的。
但是,在你调用完get后,调用put之前,
如果有另外一个线程调用了map.put(name, x),
你再去执行map.put(name,x),
就很可能把前面的操作结果覆盖掉了。
所以,即使在线程安全的情况下,
你还是有可能违反原子操作的规则。
我一般不采用ConcurrentHashMap这个类,而是采用
Map map = Collections.synchronizedMap(new HashMap());
String getString(String name) {
synchronized(map){//可保证该同步块内的所有代码对map是一个原子操作。
String x = map.get(name);
if (x == null) {
x = new String();
map.put(name, x);
}
return x;
}
}
仅是在性能、吞吐量进行优化?