jdk源码总结 二

    其实刚开始看java.util包下的类,有点懵懵的,几天看下来,包括看一些其他人的笔记,推荐大家对比着看,我是先看java.util.HashMap,java.util.Hashtable、java.util.Concurrent.ConcurrentHashMap。也是看其他人说的HashMap非线程安全,在多线程环境下,建议使用Hashtable、ConcurrentHashMap。

1.HashMap是一个用以存储键值对的集合,每一个键值对也叫做Map.Entry。这些键值对分散存储在一个数组当中。HashMap数组的元素不止是一个Map.Entry,也是一个链表的头节点。

 

0

1

2

3

4

5

6

7

数组

Null

Null

Null

Null

Null

Null

Null

Null

 

Key10

Key1

Key8

 

 

 

 

 

链表

 

 

Key4

 

 

 

 

 

链表

key0

 

Key2

 

 

 

 

 

调用put(key,value)往集合中添加一个键值对,根据hash()算法,计算出这个键值对存放的位置。如果是第一个Entry,存放在数组中,也是对应链表的头节点。如果这个索引对应的数组已经有Entry,将原来的Entry下移到链表中,新的Entry放入数组中。

2.HashMap的初始容量是16,Hashtable的初始容量是11,两者填充因子是0.75。对于这个容量和填充因子,我还是不太理解。

3.HashMap的键和值都允许为空,Hashtable的键和值都不允许为空。我只看到Hashtable对键值的null判断,如果为空,会抛出异常。但是HashMap的null判断,只看到hash()方法中有。

参考地址:https://blog.csdn.net/cn_yaojin/article/details/78790221。我看的1.8的源码,和他看的确实有差别。

4. HashMap是非线程安全的,它的put()和get()方法确实没有synchronized。而Hashtable的put()和get()方法都有Synchronize的。可是到底怎么体现呢?我反复测试也没测试出来。

我期望的结果是,因为HashMap非线程安全,所以HashMap中会出现key为ThreadA i   ,value为 ThreadB i 的或者 ThreadB i 对应 ThreadA i 的  ,就是脏数据,但是我测试的结果是没有的。

5. 判断一个键是否存在,不能用get,而用containsKey。get结果为null存在两种形式:key不存在或者value为null。

map.put("age",null);//值为空

map.get(null) 结果为null

map.get("age") 结果为null

map.containsKey(null) 结果为false

map.containsKey("age") 结果为ture

6.Hashtable和ConcurrentHashMap线程安全保证机制是否一样?Hashtable在put()和get()增加了synchronize的,锁定的是Hashtable对象,如果一个线程操作Hashtable,另一个线程必须等待。ConcurrentHashMap是将整个集合细分为多个Segment保存在Segment数组中,Segment继承自ReentrantLock。ReentrantLock锁定的是一个Segment。这里就涉及到Synchronized和lock的区别?

持续更新中,请各位指点!

发布了39 篇原创文章 · 获赞 12 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/yanweijie0317/article/details/102966544
今日推荐