再来一篇,看jdk源码大师亲自操刀编写的集合源码

16 篇文章 0 订阅
12 篇文章 0 订阅

本文首发于公众号【看点代码再上班】,欢迎围观,第一时间获取最新文章。

全文共计1959字18图,预计阅读时间13分钟

大家好,我是tin,这是我的第8篇原创文章

iShot2021-03-06 16.00.36.png

这个图拍摄于老家县城一售楼处。作为外出上班的一族,一年365天在家的时间常常不超过十天。

在侃技术前,聊一聊自己对家乡变化的感慨。

最大的感慨莫过于,我们县城要通高铁了,以后老家和工作之地的距离将变成2小时!想想就觉得这是一件多么幸福的事。

今年过年回家趁着假期和家人又新购置了一套新商品期房,就买高铁站片区边上。

iShot2021-03-06 16.54.41.png

在家买房的最大特点就是,房子面积要大的,动不动都一百多两百平,在深圳这个地方就不敢想啦。

房子本来最早于2019年已打算购置,但当时时间仓促没看好,加之2020年过年刚好遇上疫情,足不出户,一耽搁就到了2021年。

或许刚好是疫情的原因,今年房价特价销售(也就是降价了),相对2019年降了500-1000元/㎡。在这种七八线城市,房价本就几千块一平,这个降价幅度是异常高的(打心里认为,2021年是小城购房最佳时机之一)。

其实,这里唠嗑只是想感慨一下小城市的变化之大!但是我们很多人却容易忽略身边最亲近的事与物。比如我,我竟然不知我们县城的政务中心都搬迁了,整个县城南片区规划建设已相当完善,商品房、幼儿园、中小学校区、超宽大道等等随处可见,新医院、新行政办公楼、高铁站等这些似乎在缩小与大城市的差距。

这些年,国家对农村建设力度也很大,肉眼可见的变化常常被我们谈及。普遍被提到的一个变化是路变好了。村村通公路、水泥路,每年外出回家的人一定能感受到。路变好,相应的是,车也就多了。买车的人越来越多,每家都会有一辆代步小轿车。

除了车,家里爸爸妈妈们网上购物更加频繁,比起以往,老人们都可以自行网上购物,自行取快递,这种线上体验的场景规模越来越空大,所以,农村通宽带也已不是什么新鲜事。

朋友们,你们觉得呢,你们家乡还有哪些变化?

ConcurrentHashMap

我们打开ConcurrentHashMap源码,类开头鲜明地标着作者:@author Doug Lea

image.png

Doug Lea是谁?以前也有提到过,他是一位大学老师,同时也是世界上对Java影响最大的人之一。JDK源码中java.util.concurrent 包就是他创作的。

image.png

我们找到jdk1.7的源码,ConcurrentHashMap中的get方法还能看到Doug Lea的代码(下图源码截图基于jdk7-b147)

image.png

我们知道,HashMap 是线程不安全的,并发情况下使用hashmap有cpu飙升的风险。为了使用线程安全的 HashMap,我们常使用 ConcurrentHashMap。

本文基于jdk1.7讲解,所以concurrenthashmap还是采用分段锁。

image.png

ConcurrentHashmap默认有16个Segment,最多支持65536个Segment,这是可以通过ConcurrentHashMap的构造器指定的。默认情况下ConcurrencyLevel等于16

image.png

如果指定ConcurrencyLevel,最大只能等于65535

image.png

Segment通过继承ReentrantLock来进行加锁,每次锁住一个segment来保证每个Segment内的操作的线程安全性从而实现全局线程安全。

定位一个元素的过程需要进行两次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部。看看get方法的源码:

image.png

ConcurrentHashMap定义了一个Segment数组segments,Segment则定义了一个HashEntry数组table。

这种两级定位的结构带来的副作用是hash过程要比普通的HashMap要长,但是带来的好处是更大的,写操作可以只对元素所在的Segment进行加锁即可,不会影响到其他的Segment,这样,ConcurrentHashMap可以支持最大Segment数量的并发量,吞吐量就比HashMap大了很多。

细心的你可能已经发现,代码截图中使用到了UNSAFE.getObjectVolatile(segments, u),这个是什么意思呢?

getObjectVolatile是为保证并发访问数组的第 k 个元素可以显式 volatile 读取,为了值的可见性。

说到Unsafe,这玩意儿咋一看感觉很高大上,因为我们平常编程几乎没见过。但是,Unsafe现在在Java里面是一个“擦边球”,基本处于一个“不推荐使用”的状态。

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等。因为可以访问系统资源、可以自主操作内存空间,这无疑增加了程序发生指针问题的风险,Java的垃圾回收器本来很大一个原因是为了解决这个问题,使用Unsafe类会使得程序出错的概率变大,Java官方也不建议开发者使用它。

R大有一篇回答,关于Unsafe,为什么JUC中大量使用了sun.misc.Unsafe 这个类,但官方却不建议开发者使用? - 知乎

结语

我是tin,一个在努力让自己变得更优秀的普通攻城狮。自己阅历有限、学识浅薄,如有发现文章不妥之处,非常欢迎加我提出,我一定细心推敲加以修改。

看到这里请安排个“三连”(分享、点赞、在看)再走吧,坚持原创不容易,不要白嫖,你的正反馈是我坚持输出的最强大动力,谢谢!

20190911181805AMQR5B8FDFDAXGLA.gif

最后别忘了关注我哦!⏬⏬⏬

qrcode_for_gh_e635d95b89a2_258-2.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值