HashMap和ConcurrentHashMap的简单认识

ConcurrentHashMap

我记得我曾经在HashMap的文章(点击可查看)里说过,HashMap不是线程安全的,在高并发状态下,HashMap调用transfer方法,可能会出现环形链表,导致程序死循环,为了解决这个问题.当然,解决这个问题,可以用Hashtable或者Collections.synchronizedMap,不过,这两种问题都会出现一个新的问题:性能.会造成阻塞.所以,在高并发下,既要保证安全,又要保证性能问题,就产生了ConcurrentHashMap.
当然,以我目前的水平,无法深入了解ConcurrentHashMap.所以,我这里只是简单的说一下ConcurrentHashMap的一些表面知识.
这里写图片描述

ConcurrentHashMap的key和value都不能为null

例子:

public class ConcurrentHashMapDemo {

    public static void main(String[] args) {
        ConcurrentHashMap<String, String> cm = new ConcurrentHashMap<String,String>();
        cm.put(null, "马");
        //cm.put("屁", null);        
    }
}

key为null:
这里写图片描述

value为null:
这里写图片描述

源码:
这里写图片描述
在put的源码里,会先判断value是否为null,如果是null,就会抛出空指针异常
这里写图片描述
如果value不为null,就会用key去计算hash值,在计算时,会报空指针异常

高并发时,ConcurrentHashMap怎么保证安全和性能问题

HashMap和ConcurrentHashMap的数据结构
这里写图片描述

如果看不懂这张图的话,看下面两张图
这里写图片描述
这里写图片描述

在ConcurrentHashMap中,一个segment就是一个HashMap对象,而且因为ConcurrentHashMap采用了锁分段技术,所以每一个segment就好比一个自治区,读写操作高度自治,segment之间互不影响,不过由于segment的写入是需要上锁的,因此对同一segment的并发写入会被阻塞.
结论:ConcurrentHashMap当中每个Segment各自持有一把锁。在保证线程安全的同时降低了锁的粒度,让并发操作效率更高。

关于ConcurrentHashMap的get()和put()的一些东西

get方法:
a) 为输入的key做hash运算,得到hash值
b) 通过hash值,定位到对应的segment对象
c) 再次通过hash值,定位到segment当中数组的具体位置
put方法:
1) 为输入的key做hash运算,得到hash值
2) 通过hash值,定位到对应的segment对象
3) 获取可重入锁
4) 再次通过hash值,定位到segment当中数组的具体位置
5) 插入或覆盖hashEntry对象
6) 释放锁

以上这些内容,都说我在网上一些大神的文章里看到的,当然我这里只是说了个表面,如果大家想要深入了解的话,最好去把那些大神们的文章看看.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值