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());
    }

解决方案 »

  1.   

    ConcurrentHashMap 是一个线程安全的实现。不用再额外地同步。 
      

  2.   

    ConcurrentHashMap:
    支持检索的完全并发和更新的所期望可调整并发的哈希表。此类遵守与 Hashtable 相同的功能规范,并且包括对应于 Hashtable 的每个方法的方法版本。不过,尽管所有操作都是线程安全的,但检索操作不 必锁定,并且不 支持以某种
    防止所有访问的方式锁定整个表。此类可以通过程序完全与 Hashtable 进行互操作,这取决于其线程安全,而与其同
    步细节无关。 CopyOnWriteArrayList:
    ArrayList 的一个线程安全的变体,其中所有可变操作(添加、设置,等等)都是通过对基础数组进行一次新的复制来
    实现的。这一般需要很大的开销,但是当遍历操作的数量大大超过可变操作的数量时,这种方法可能比其他替代方法更
    有效。在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时,它也很有用。
      

  3.   

    补充一下:
    虽然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),
    就很可能把前面的操作结果覆盖掉了。
    所以,即使在线程安全的情况下,
    你还是有可能违反原子操作的规则。
      

  4.   

    非常赞同3楼的说法,遇到这种情况。
    我一般不采用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;
            } 
        } 
      

  5.   

    Map map = Collections.synchronizedMap(new HashMap());比用ConcurrentHashMap会差了很多啊
      

  6.   

    谢谢楼上诸位,也就是说ConcurrentHashMap和synchronizedMap、hashtable在用法上没有什么区别么?
    仅是在性能、吞吐量进行优化?
      

  7.   

    sorry,not 吞吐量 but 伸缩性
      

  8.   

    ConcurrentHashMap有putIfAbsent(),CopyOnWriteArrayList有addIfAbsent(),使你能方便的实现检查然后操作的原子化。
      

  9.   

    3楼提出的问题确实存在,但这个不是ConcurrentHashMap存在的问题,是使用者在写代码时没考虑周全的问题。
      

  10.   

    berdy 说的对.concurrentHashMap原子是一定的, 然而可见性并不是一定的.