同步map的学习

首先,先说明map。Map用于存储“key-value”元素对,它将一个key映射到一个而且只能是唯一的一个value。Map可以使用多种实现方式,HashMap的实现采用的是hash表;而TreeMap采用的是红黑树。

  1. HashTable 和 HashMap的不同

    它们都实现了Map接口,但HashTable还实现了Dictionary抽象类。在HashMap中,null可以作为键也可以作为值,所以不能用get方法来判断map中是否含有见,而是必须用containsKey方法来判断。而在HashTable中,无论是键还是值,都不能用null。

    最大的不同则在于HashTable为线程安全的,它的方法都是同步了的,可以直接在多线程环境下使用。HashMap则不是线程安全的,在多线程环境下,需要手动实现同步机制。Java中Collections类提供了一个方法用于返回一个同步版本的HashMap以便用于多线程环境中。

 Java代码

  1. public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {   

  2.     return new SynchronizedMap<K,V>(m);   

  3.  }

 但这样返回的SynchronizedMap页并不是时时都线程安全的,比如,在判断了元素存在之后,进行删除操作,此时若有另一个线程页判断元素存在,要进行删除操作是却发现元素已经不存在了就会抛出异常。

2. 更好的选择:ConcurrentHashMap

ConcurrentHashMap提供了一种与HashTable和SynchronizedMap中不同的锁机制。HashTable采用的锁机制是一次锁住整个整个hash表,从而同一时刻只能由同一个线程进行操作。而ConcurrentMap则是一次锁住一个桶,默认将Hash表分为16个桶。get、put、remove操作只需锁住最常用的桶。现在可以有16个进程并发执行。而读操作一般不需要锁,只有size是需锁住整个hash表。

在迭代方面,ConcurrentHashMap页采取了一种新的迭代方式。iterator被创建后在发生改变也不会抛出ConcurrentModificationException异常,而是在改变是new新的数据,从而不影响原有的数据,在迭代完成后再将头指针替换为新的数据。这样读进程可以读取原有数据,而写进程也可以并发的改变数据。

你可能感兴趣的:(同步map的学习)