java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别
目录
- 如果此时有两个线程,线程一完成resize,结果如下
-
此前线程二之前只执行了第一层Entry
-
执行497到501的代码
- while(e!=null),此时e为7,e不为空,进入第二次循环
- next=e.next,即next为7的next(这个是判断后面循环是否终止),也就是3(线程一的结果),把7放到链表前头
-
while(e!=null),此时e=3,e不等于null,进入第三次循环
-
next=e.next(这个是判断后面循环是否终止),即3的next,也就是null(造成后面循环终止)
-
放置3这个Entry,3的next设为7(e.next = newTable[i];),而上一步7的next是3,这样就造成了一个循环
- while(e!=null),e为null循环终止
- 那么如果此时get一个键,如果这个键的hash值刚好和3相同,那么这个时候就会遍历链表进行查找,而这个链表是个循环链表,就会造成死循环
- 因此hashmap并不是线程安全
HashTable
对比
public synchronized V get(Object key){} public synchronized V put(K key, V value) {} public synchronized V remove(Object key){}
- 用一个表来描述HashMap和HashTable的主要区别
对比 HashMap HashTable 键值 键和value允许null 不行 synchronized 非synchronzied synchronized 单线程情况下速度 快 慢 扩容方式 2倍 2倍+1 容量 初始为16,必须为2的n次方 初始为11 缺点
- 单线程情况下,也会加锁
ConcurrentHashMap
HashEntry类
static final class HashEntry<K,V> { 219 final K key; 220