3-4-Map映射

文章目录
  1. 1. 非线程安全
    1. 1.1. 1.hashmap
      1. 1.1.1. jdk7数组+链表
      2. 1.1.2. jdk8数组+链表/红黑树
        1. 1.1.2.1. 元素大于8,链表转换为红黑树
    2. 1.2. 2.treemap可排序
    3. 1.3. 3.linkedhashmap(记录插入顺序)
      1. 1.3.1. 可实现redis lru(latest recently use)算法
  2. 2. 线程安全
    1. 2.1. 1.concurrentHashMap[segment数组]
      1. 2.1.1. Segment(段,继承reentrantlock,jdk7)
      2. 2.1.2. 并行度(多少个segment并发操作,默认16)
    2. 2.2. 2.ConcurrentSkipListMap跳表有序(jdk6)
      1. 2.2.1. Skip list的性质
      2. 2.2.2. ConcurrentSkipListMap优点:
    3. 2.3. 3.hashtable(全局锁,只有一个线程并发)
    4. 2.4. 4.SynchronizedMap(效率和hashtable差不多)
    5. 2.5. 5. Collections.synchronizedSortedMap(并行度比skiplistmap低,也是有序)

非线程安全

1.hashmap

  1. 根据hashcode存储数据,容易直接定位到它的值。遍历顺序不确定。

jdk7数组+链表

一个数据,数组中每个元素是一个单向链表。每个实体是嵌套类entry实例(四个属性:key, value, hash值,单向链表的next)。

  1. capacity: 当前数据容量,扩容数组大小为当前2倍。
  2. loadfactor:负载因子,默认0.75。就是到这个比例就扩容。
  3. threshold:扩容的阈值。

jdk8数组+链表/红黑树

元素大于8,链表转换为红黑树

链表最差的时间复杂度为o(n)。红黑树时间复杂度度降低到o(logN)。

2.treemap可排序

  1. 实现 SortedMap 接口
  2. 用 Iterator 遍历 TreeMap 时,得到的记录是排过序的。(实现 Comparable 接口)

3.linkedhashmap(记录插入顺序)

可实现redis lru(latest recently use)算法

线程安全

1.concurrentHashMap[segment数组]

Segment(段,继承reentrantlock,jdk7)

整个 ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多地方都会将其描述为分段锁。

ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。

并行度(多少个segment并发操作,默认16)

理论上,这个时候,最多可以同时支持 16 个线程并发写,只要它们的操作分别分布在不同的 Segment 上。这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。

2.ConcurrentSkipListMap跳表有序(jdk6)

和TreeMap效率相差不大。

Skip list的性质

(1) 由很多层结构组成,level是通过一定的概率随机产生的。
(2) 每一层都是一个有序的链表,默认是升序,也可以根据创建映射时所提供的Comparator进行排序,具体取决于使用的构造方法。
(3) 最底层(Level 1)的链表包含所有元素。
(4) 如果一个元素出现在Level i 的链表中,则它在Level i 之下的链表也都会出现。
(5) 每个节点包含两个指针,一个指向同一链表中的下一个元素,一个指向下面一层的元素。

ConcurrentSkipListMap优点:

1、ConcurrentSkipListMap 的key是有序的

2、ConcurrentSkipListMap 支持更高的并发。ConcurrentSkipListMap 的存取时间是log(N),和线程数几乎无关。也就是说在数据量一定的情况下,并发的线程越多,ConcurrentSkipListMap越能体现出他的优势。

3.hashtable(全局锁,只有一个线程并发)

任一时间只有一个线程能写 Hashtable,并发性不如 ConcurrentHashMap,因为 ConcurrentHashMap 引入了分段锁。

4.SynchronizedMap(效率和hashtable差不多)

这个同步方式实现也比较简单,看出SynchronizedMap的实现方式是加了个对象锁,每次对HashMap的操作都要先获取这个mutex的对象锁才能进入,所以性能也不会比HashTable好到哪里去,也不建议使用。

5. Collections.synchronizedSortedMap(并行度比skiplistmap低,也是有序)