Netty源码阅读8——FastThreadLocal

Posted by 皮皮潘 on 12-06,2021

在ThreadLocal实现中,为了防止多线程对于内置Map<ThreadId, Object>的并发访问带来的性能损耗以及加锁问题,ThreadLocal采用了相反的方式,将对应的Map<ThreadId,Object>转化为了Map<ThreadLocalId,Object>并放置到了Thread中,也即在每个Thread中存在一个将ThreadLocalId映射到Object的Map,当Thread访问ThreadLocal时实际会访问自身内部的Map,从而解决了并发访问的问题。但是该实现需要Thread去主动地和ThreadLocl配合:本来Thread是对于ThreadLocal无感知,现在需要在Thread中存在一个类型为ThreadLocal.ThreadLocalMap的变量

在ThreadLocalMap中采用了线性探测的方式去解决Hash冲突问题,也即在写入发生冲突的时候,顺位往后寻找空的Slot,而在get的时候也会线性地通过将key和Entry的key去比对来确定真正的value

在Netty中进一步优化了ThreadLocl成为了FastThreadLocal,而与FastThreadLocal一起配合的Thread也自然叫做FastThreadLocalThread,其中主要对于Map进行了优化,通过全局化的AtomicInteger,每个FastThreadLocal拥有了全局唯一的id,而Map底层也采用了数组的方式进行存储,也即每个FastThreadLocal全局唯一的id对应了数组的下标,虽然这也引入了扩容以及空间的额外开销,但是也带来了更好的读取性能

除此之外,由于FastThreadLocal需要和FastThreadLocalThread的FastThreadLocalMap类型成员字段配合使用,当用户使用普通Thread的时候,Netty用Thread的ThreadLocal存储了FastThreadLocalMap从而达到相同效果,但是速度会比较慢,因此还是建议FastThreadLocal和FastThreadLocalThread配合使用