惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

接着上次手撕面试题ThreadLocal!!!面试官一听,哎呦不错哦!本文将继续上文的话题,来聊聊FastThreadLocal,目前关于FastThreadLocal的很多文章都有点老有点过时了(本文将澄清几个误区),很多文章关于FastThreadLocal介绍的也不全,希望本篇文章可以带你彻底理解FastThreadLocal!!!

FastThreadLocal是Netty提供的,在池化内存分配等都有涉及到!​

关于FastThreadLocal,零度准备从这几个方面进行讲解:

FastThreadLocal的使用。

FastThreadLocal并不是什么情况都快,你要用对才会快。

FastThreadLocal利用字节填充来解决伪共享问题。

FastThreadLocal比ThreadLocal快,并不是空间换时间。

FastThreadLocal不在使用ObjectCleaner处理泄漏,必要的时候建议重写onRemoval方法。

FastThreadLocal为什么快?

FastThreadLocal的使用

FastThreadLocal用法上兼容ThreadLocal

FastThreadLocal使用示例代码:

public class FastThreadLocalTest { private static FastThreadLocal<Integer> fastThreadLocal = new FastThreadLocal<>(); public static void main(String[] args) { //if (thread instanceof FastThreadLocalThread) 使用FastThreadLocalThread更优,普通线程也可以 new FastThreadLocalThread(() -> { for (int i = 0; i < 100; i++) { fastThreadLocal.set(i); System.out.println(Thread.currentThread().getName() + "====" + fastThreadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } }, "fastThreadLocal1").start(); new FastThreadLocalThread(() -> { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "====" + fastThreadLocal.get()); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } }, "fastThreadLocal2").start(); } }

代码截图:

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

代码运行结果:

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

我们在回顾下之前的ThreadLocal的 最佳实践做法:

try { // 其它业务逻辑 } finally { threadLocal对象.remove(); }

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

备注: 通过上面的例子,我们发现FastThreadLocal和ThreadLocal在用法上面基本差不多,没有什么特别区别,个人认为,这就是FastThreadLocal成功的地方,它就是要让用户用起来和ThreadLocal没啥区别,要兼容!

使用FastThreadLocal居然不用像ThreadLocal那样先try ………………… 之后finally进行threadLocal对象.remove();

由于构造FastThreadLocalThread的时候,通过FastThreadLocalRunnable对Runnable对象进行了包装:

FastThreadLocalRunnable.wrap(target)从而构造了FastThreadLocalRunnable对象。

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

FastThreadLocalRunnable在执行完之后都会调用FastThreadLocal.removeAll();

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

备注: 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

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

备注: 在我本地进行测试,FastThreadLocal的吞吐量是jdkThreadLocal的3倍左右。机器不一样,可能效果也不一样,大家可以自己试试,反正就是快了不少。

关于ThreadLocal,之前的这篇:手撕面试题ThreadLocal!!!已经详细介绍了。

FastThreadLocal并不是什么情况都快,你要用对才会快!!!

注意: 使用FastThreadLocalThread线程才会快,如果是普通线程还更慢!
注意: 使用FastThreadLocalThread线程才会快,如果是普通线程还更慢!
注意: 使用FastThreadLocalThread线程才会快,如果是普通线程还更慢!

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

netty的测试目录下面有2个类:

FastThreadLocalFastPathBenchmark

FastThreadLocalSlowPathBenchmark

路径:https://github.com/netty/netty/blob/4.1/microbench/src/main/java/io/netty/microbench/concurrent/

FastThreadLocalFastPathBenchmark测试结果: 是ThreadLocal的吞吐量的3倍左右。

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

FastThreadLocalSlowPathBenchmark测试结果: 比ThreadLocal的吞吐量还低。

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

测试结论: 使用FastThreadLocalThread线程操作FastThreadLocal才会快,如果是普通线程还更慢!

惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

注释里面给出了三点:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfxyf.html