zoukankan      html  css  js  c++  java
  • Java Map 知识

    ConcurrentHashMap的一个NullPointerException异常引起,结合ConcurrentHashMap源码分析为什么ConcurrentHashMap不允许空key和value以及如何改造进行支持

    1、异常分析
    今天碰到一个异常,信息如下:

    本以为是并发异常,后发现不对,因为ConcurrentHashMap已经使用继承自ReentrantLock的Segment,保证了线程安全,Java如果有这么大的bug肯定早修复了。看了下源码

    ConcurrentHashMapRemove

    发现自己大意了,在获取hashCode时NPE(hashMap不会,因为它会对null key做一次处理)。ConcurrentHashMap不接受null key和null value这个常识一时疏忽了,调用的地方确实有可能传入null。这样在remove前进行null判断即可解决。

    在问题解决后,想到hashMap和linkedhashMap都允许null key和null value,treeMap不允许null key,但允许null value,而ConcurrentHashMap既不允许null key也不允许null value,why?

    2、not allow null key and value
    stackoverflow并结合了源码分析了一下
    (1) treeMap不允许null key是因为compare会导致NPE, 可通过以下代码实现null key支持

    (2) ConcurrentHashMap不允许null key和null value,是因为ConcurrentHashMap的锁机制
    对于get(Object key)如果返回null,ConcurrentHashMap没办法判断是key不存在还是value就是null。有人得问了那么hashmap呢, 为什么可以,hashmap我们可以通过下面代码实现判断

    使用Collections.synchronizedMap对hashmap加锁,Collections.synchronizedMap的锁是同步锁,就是对象本身,所以synchronized (map)与Collections.synchronizedMap内锁统一。而ConcurrentHashMap的并发控制是利用分离锁实现的(16个重入锁),在外部无法获得锁,自己也没有提供函数进行判断,所以无奈了。

    那么有没有办法既保证map的并发安全同时又允许null key和null value呢,当然了,两种方式
    第一种实际上面已经展现了,通过Collections.synchronizedMap对hashmap加锁即可。synchronizedMap保证了线程安全,hashmap又允许null key和null value。

    不过Collections.synchronizedMap的并发性能自然比不上ConcurrentHashMap的分桶锁机制,如果对性能要求较高
    理论上也可以重写ConcurrentHashMap添加一个函数支持上面代码段的并发,但这个要求对ConcurrentHashMap的分离锁相当熟悉。

    Reference: http://www.trinea.cn/android/android-source-code-analysis/concurrenthashmap-nullpointerexception-null-key/

    Time is going......
  • 相关阅读:
    在ASP.Net和IIS中删除不必要的HTTP响应头
    Json对象与Json字符串互转
    Jquery ajax传递复杂参数给WebService
    HTTP的KeepAlive是开启还是关闭?
    MQ产品比较-ActiveMQ-RocketMQ
    RocketMQ(7)——通信协议
    mq使用经验
    mq
    RocketMQ
    发送短信验证码实现方案
  • 原文地址:https://www.cnblogs.com/shua/p/4450315.html
Copyright © 2011-2022 走看看