前言
最近在看dubbo源码的时候,忽然发现一个乏味的事件,dubbo有一小部分代码是一成不变的剽窃Netty代码。间接上图:
dubbo源码:
Netty源码:
能够看到,Dubbo只是改了个类名(FastThreadLocal -> InternalThreadLocal),连正文都照搬过去了!并美其名曰“借鉴”Netty的设计思路。的确,代码人的事件怎么能叫剽窃呢?嘿嘿。
正题
不过话说回来,尽管是剽窃,但也正阐明了Netty的FastThreadLocal设计思路十分好,才会让Dubbo的开发者将它也引入了Dubbo外部。上面咱们就来看看FastThreadLocal的设计思路和实现原理吧。
设计思路
从正文上能够看到,FastThreadLocal采纳数组下标的形式,代替了JDK原生的hash code + hash table的形式,尽管改变不大,但在频繁拜访的场景下,也能晋升性能。
它有个应用前提,那就是咱们的线程Thread必须是FastThreadLocalThread的实现类或子类,因而Netty外部的默认ThreadFactory创立的都是FastThreadLocalThread类型,如果是其余Thread类型,会进化到JDK的ThreadLocal。
实现原理
(ps:胃病犯了,下次补充上,有趣味的童鞋能够本人去翻看下,有急躁的童鞋能够点个关注,下次肯定更新!对,下次肯定!嘻嘻)
小插曲
另外我在看Dubbo的SPI局部源码时,还发现了一件乏味的事件,有位热心的开源贡献者给Dubbo提交了PR,说是JDK1.8的ConcurrentHashMap#computeIfAbsent()办法有bug,就把它换成了putIfAbsent(),并被Dubbo的commiter review通过并合入了。PR链接:https://github.com/apache/dub...
这位开源贡献者还把这个jdk官网bug的记录列表收回来了
https://bugs.openjdk.java.net...
带着好奇心,我也关上了这个bug链接,说的是如果在computeIfAbsent()办法外面递归调用computeIfAbsent()的话,有几率呈现死循环bug,这个几率指的是哈希碰撞的时候。具体看bug形容吧:
死循环样例代码:
这个bug只有在递归调用的时候才有几率呈现死循环,并且ConcurrentHashMap的作者Doug Lea巨匠,在JDK1.9版本的解决办法也只是在检测到递归调用的时候抛出异样,阐明不举荐用户递归调用:
也就是说,只有咱们不递归调用computeIfAbsent,就不会呈现死循环bug,显然dubbo这里没有违反这公约定,天然不会呈现死循环bug,挺好奇过后commiter是怎么review通过并merge的呢?
这两件事,让我领会到,哪怕是Dubbo这样出名的Apache顶级我的项目,也有这样那样的缺点,阐明大牛们也是人,不是神,也会犯错,这让我更加有自信,来参加到开源社区中了!