目前关于FastThreadLocal的很多文章都有点老有点过时了(本文将澄清几个误区),很多文章关于FastThreadLocal介绍的也不全,希望本篇文章可以带你彻底理解FastThreadLocal!!!
FastThreadLocal是Netty提供的,在池化内存分配等都有涉及到!
关于FastThreadLocal,零度准备从这几个方面进行讲解:
- FastThreadLocal的使用。
- FastThreadLocal并不是什么情况都快,你要用对才会快。
- FastThreadLocal利用字节填充来解决伪共享问题。
- FastThreadLocal比ThreadLocal快,并不是空间换时间。
- FastThreadLocal不在使用ObjectCleaner处理泄漏,必要的时候建议重写onRemoval方法。
- FastThreadLocal为什么快?
FastThreadLocal的使用
FastThreadLocal用法上兼容ThreadLocal
FastThreadLocal使用示例代码截图:
代码运行结果:
我们在回顾下之前的ThreadLocal的最佳实践做法:
try { // 其它业务逻辑 } finally { threadLocal对象.remove(); }
备注:通过上面的例子,我们发现FastThreadLocal和ThreadLocal在用法上面基本差不多,没有什么特别区别,个人认为,这就是FastThreadLocal成功的地方,它就是要让用户用起来和ThreadLocal没啥区别,要兼容!
使用FastThreadLocal居然不用像ThreadLocal那样先try ………………… 之后finally进行threadLocal对象.remove();
由于构造FastThreadLocalThread的时候,通过FastThreadLocalRunnable对Runnable对象进行了包装:
FastThreadLocalRunnable.wrap(target) 从而构造了FastThreadLocalRunnable对象。
FastThreadLocalRunnable在执行完之后都会调用FastThreadLocal.removeAll();
备注: FastThreadLocal不在使用ObjectCleaner处理泄漏,必要的时候建议重写onRemoval方法。关于这块将在本文后面进行介绍,这样是很多网上资料比较老的原因,这块已经去掉了。 如果是普通线程,还是应该最佳实践: finally { fastThreadLocal对象.removeAll(); } 注意: 如果使用FastThreadLocal就不要使用普通线程,而应该构建FastThreadLocalThread,关于为什么这样,关于这块将在本文后面进行介绍:FastThreadLocal并不是什么情况都快,你要用对才会快。
FastThreadLocal并不是什么情况都快,你要用对才会快
首先看看netty关于这块的测试用例:
代码路径:
https://github.com/netty/netty/blob/4.1/microbench/src/main/java/io/netty/microbench/concurrent/FastThreadLocalFastPathBenchmark.java