jdk1.7 HashMap涉及知识点

在看关于HashMap 1.7 BUG时,即多线程时会导致死锁。从而去查找相关资料,看看到底是什么原因造成的。

总结一下,在看HashMapsh源码中涉及到知识点:`

1. java运算符 与(&)、非(~)、或(|)、异或(^)

  • 位异或运算(^): 两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
  • 位与运算符(&): 两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。
  • 位或运算符(|): 两个数都转为二进制,然后从高位开始比较,两个数只要有一个为1则为1,否则就为0。
  • 位非运算符(~): 如果位为0,结果是1,如果位为1,结果是0.
  • >>:带符号右移。正数右移高位补0,负数右移高位补1
  • >>>:无符号右移。无论是正数还是负数,高位通通补0

2. HashMap多线程死循环,这个是jdk BUG资料也最多,很多都是贴代码,如下:

void transfer(Entry[] newTable, boolean rehash) {

    int newCapacity = newTable.length;

    for (Entry<K,V> e : table) {

        while(null != e) {

            Entry<K,V> next = e.next;

            if (rehash) {

                e.hash = null == e.key ? 0 : hash(e.key);

            }

            int i = indexFor(e.hash, newCapacity);

            e.next = newTable[i]; //注意这条语句

            newTable[i] = e; //注意这条语句

            e = next;

        }

    }

}

transfer方法代码解释:

1、原来的table进行两层遍历,外层遍历table,内层遍历table索引处的链表,从链头遍历到链尾。

2、从原来的链表取出头节点e,计算e的hash值以及在新的table中的bucketIndex值i。newTable[i]指向数组下标对应的元素,

也就是指向数组bucketIndex对应链表的头节点。用e.next指向原先的头节点引用newTable[i],newTable[i]再指向e,把e作为新的头节点。

3、不要忘了我们要不断从原来的链表取出头节点e,直到遍历到链尾为止。所以我们要在2操作开始之前,

Entry<K,V> next = e.next; 用next变量指向原来链表的下一个头节点,

在2操作执行完后, e = next;使e重新成为原来链表的头节点。

参考:hashmap死循环示例及检测方法

总结:说白了,还是不是很直观,怎么才能模拟出来这段代码是不是存在问题呢?反正我没有模拟出来

3. 泊松分布

一句话解释:泊松分布是单位时间内独立事件发生次数的概率分布,指数分布是独立事件的时间间隔的概率分布。

这个概念由容量因子引出来的:static final float DEFAULT_LOAD_FACTOR = 0.75f; //HashMap默认值

容量因子的作用:就是在HashMap的size大于size*0.75的时候,会自动进行扩容

但是源码中后面还跟了一个条件:if((size >= threshold) && (null != table[bucketIndex])){resize(2size)}, 即数组所在位置不为空的情况下,就说说发现那个table[i]有数据了才能进行扩容操作*

参考:泊松分布

问题1:为什么默认初始化桶数组大小为16,为什么加载因子的大小为0.75.这两个值的选取有什么特点

通过看上面的代码我们可以知道这两个值主要影响的threshold的大小,
这个值的数值是当前桶数组需不需要扩容的边界大小,

我们都知道桶数组如果扩容,会申请内存空间,
然后把原桶中的元素复制进新的桶数组中,这是一个比较耗时的过程。
既然这样,那为何不把这两个值都设置大一些呢,
threshold是两个数的乘积,设置大一些就不那么容易会进行扩容了啊。

原因是这样的,如果桶初始化桶数组设置太大,就会浪费内存空间,
16是一个折中的大小,既不会像1,2,3那样放几个元素就扩容,
也不会像几千几万那样可以只会利用一点点空间从而造成大量的浪费。
加载因子设置为0.75而不是1,是因为设置过大,桶中键值对碰撞的几率就会越大,
同一个桶位置可能会存放好几个value值,这样就会增加搜索的时间,性能下降,设置过小也不合适,
如果是0.1,那么10个桶,threshold为1,你放两个键值对就要扩容,太浪费空间了。

总结:0.75和泊松分布没有必然联系,看你怎么理解了,我觉得可以3/4方便计算,毕竟map的size都是2的幂次方

4. Eclipse中debug jdk源码

在debug hashmap时,发现变量都没有值,所以搜索了一下是否支持源码debug,还真有。

参考:设置Eclipse可以Debug模式调试JDK源码,并显示局部变量的值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355