看到很多文章说hashtable之所以被取代,原因在于它是线程同步的,因而效率比较低。
但是我在想,如果用不同步的HashMap,那当多个线程访问时,岂不是会出现数据不一致的现象?
所以我想hashtable被取代的前提是不是应该是在单线程环境下?

解决方案 »

  1.   

    HashMap多线程读的时候是线程安全的,remove、put等修改操作是才需要同步。
    但很多测试表明,在高并发下HashTable并不是绝对线程安全。通常在多线程下是用ConcurrentHashMap来替代HashMap或HashTable。
      

  2.   

    能问个问题吗 HashTable并不是绝对线程安全怎么说呢 有资料吗?
      

  3.   


    java.util下集合类的Iterator迭代器都是线程不安全的,不光是HashTable,Vector也一样。如果你通过Iterator去并发修改(或修改的同时读取),同样会造成ConcurrentModificationException。
      

  4.   

    嗯,不过从字面理解,我觉得这个恰恰是线程安全机制作用下的表现之一
    因为如果并发修改,就会造成冒其在未来某个不确定的时间,一个任意或不确定的表现的风险,这只能说明它的iterator是不允许被并发修改的而且在HashTable doc的最后一段,Vector也同样是这句话:
    As of the Java 2 platform v1.2, this class was retrofitted to implement the Map interface, making it a member of the Java Collections Framework. Unlike the new collection implementations, Hashtable is synchronized. 
    可以相信HashTable是线程安全的吧
    里面有些小的细节,我还不是很清楚,比如HashTable的
    The Enumerations returned by Hashtable's keys and elements methods are not fail-fast. 
    既然其keys和elements方法返回的Enumerations不是fail-fast的,如何保证线程安全?除非它是允许并发修改的还有:
    Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
    说fail-fast在非同步的并发修改下也不是有严格保证的,这些表述就让人有些疑惑了
      

  5.   

    所以说ConcurrentHashMap才是真正的支持并发的,HashTable和HashMap是有条件的线程安全,ConcurrentHashMap是绝对线程安全,它的Iterator迭代机制也允许并发操作。
    参考下:
    http://www.ibm.com/developerworks/cn/java/j-jtp09263/
    http://www.ibm.com/developerworks/java/library/j-jtp08223/
      

  6.   

    实际上 HashMap 正在被 ConcurrentHashMap 取代。ConcurrentHashMap 是采用分离锁实现非常高效的同步 Map
      

  7.   

    一般普通的同步就使用一把监视对象锁,而 ConcurrentHashMap 默认使用了 16 把监视对象锁,也就是说默认情况下最多允许 16 个线程并发访问。在访问时具体用哪一把锁,是根据 Map key 的 hashCode 取模而来的。同步容器(java.util.concurrent 包中的)在各方面都是值得使用的,但是这些高效的同步容器有个缺点,就是他们的 size() 所返回的值并不一定是容器中真实的数据量。
      

  8.   

    thank you guys, 希望以后针对某一点进行更多更深入的讨论:)