jdk自带的ThreadLocal和netty扩展的FastThreadLocal比较总结
最近在分析一潜在内存泄露问题的时候,jmap出来中有很多的FastThreadLocalThread实例,看了下javadoc,如下:
A special variant of ThreadLocal
that yields higher access performance when accessed from a FastThreadLocalThread
.
Internally, a FastThreadLocal
uses a constant index in an array, instead of using hash code and hash table, to look for a variable. Although seemingly very subtle, it yields slight performance advantage over using a hash table, and it is useful when accessed frequently.
To take advantage of this thread-local variable, your thread must be a FastThreadLocalThread
or its subtype. By default, all threads created by DefaultThreadFactory
are FastThreadLocalThread
due to this reason.
Note that the fast path is only possible on threads that extend FastThreadLocalThread
, because it requires a special field to store the necessary state. An access by any other kind of thread falls back to a regular ThreadLocal
.
简单地说,就是在FastThreadLocalThread线程内访问性能会更快的
ThreadLocal的一种实现。其使用常量索引而非hash值作为索引进行变量查找。
对于使用默认线程池的情况,netty会使用DefaultTrheadFactory创建FastThreadLocalThread线程,而非原生的Thread,其源码位置如下:
根据之前对比java测试c++各种map、unordered_map的记忆,一般来说map中值越多、各种实现的差距越大(因为潜在的冲突增加以及底层的实现为b*或者链表或者线性等)。
为了大概了解下差距会有多少,搜了下,有个帖子(https://my.oschina.net/andylucc/blog/614359)进行了测试,例子中结果如下:
1000个ThreadLocal对应一个线程对象的100w次的计时读操作:
ThreadLocal:3767ms | 3636ms | 3595ms | 3610ms | 3719ms
FastThreadLocal: 15ms | 14ms | 13ms | 14ms | 14ms
1000个ThreadLocal对应一个线程对象的10w次的计时读操作:
ThreadLocal:384ms | 378ms | 366ms | 647ms | 372ms
FastThreadLocal:14ms | 13ms | 13ms | 17ms | 13ms
1000个ThreadLocal对应一个线程对象的1w次的计时读操作:
ThreadLocal:43ms | 42ms | 42ms | 56ms | 45ms
FastThreadLocal:15ms | 13ms | 11ms | 15ms | 11ms
100个ThreadLocal对应一个线程对象的1w次的计时读操作:
ThreadLocal:16ms | 21ms | 18ms | 16ms | 18ms
FastThreadLocal:15ms | 15ms | 15ms | 17ms | 18ms
上面的实验数据可以看出,当ThreadLocal数量和读写ThreadLocal的频率较高的时候,传统的ThreadLocal的性能下降速度比较快,而Netty实现的FastThreadLocal性能比较稳定。上面实验模拟的场景不够具体,但是已经在一定程度上我们可以认为,FastThreadLocal相比传统的的ThreadLocal在高并发高负载环境下表现的比较优秀。
总结来说,根据经验,个人认为99%的应用中不会使用超过成千上万个线程本地变量,所以除非极为特殊的应用,出于后续维护成本的考虑,使用传统的ThreadLocal就可以了,没必要使用FastThreadLocal。
PS:关于threadlocal的场景,就不重复阐述了,可参考下列两个帖子:
https://my.oschina.net/clopopo/blog/149368
http://blog.csdn.net/lufeng20/article/details/24314381
http://lavasoft.blog.51cto.com/62575/51926/
jdk自带的ThreadLocal和netty扩展的FastThreadLocal比较总结的更多相关文章
- 深度揭秘Netty中的FastThreadLocal为什么比ThreadLocal效率更高?
阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...
- JDK自带线程池学习
JDK自带线程池 线程池的状态 线程有如下状态 RUNNING状态:Accept new tasks and process queued tasks SHUTDOWN状态:Don't accept ...
- JDK自带的日志Logging
OK,现在我们来研究下JDK自带的日志Logger. 从jdk1.4起,JDK开始自带一套日志系统.JDK Logger最大的优点就是不需要任何类库的支持,只要有Java的运行环境就可以使用. 相对于 ...
- JDK 自带的观察者模式源码分析以及和自定义实现的取舍
前言 总的结论就是:不推荐使用JDK自带的观察者API,而是自定义实现,但是可以借鉴其好的思想. java.util.Observer 接口源码分析 该接口十分简单,是各个观察者需要实现的接口 pac ...
- [转]JDK自带工具之问题排查场景示例
最近看到了大量关于java性能调优.故障排查的文章,自己也写了一篇Java调优经验谈.接着此篇文章,其实一直打算写写一些常用调优工具以及它们的惯常用法的.后来在http://java-performa ...
- 011 - JDK自带的性能监控工具
一.概要: jps -l 查看现有的java进程 jps -l 显示所有正在运行的java进程id jstack 查看Java线程 jstack -l pid; 做thread du ...
- JDK自带工具之问题排查场景示例
最近看到了大量关于java性能调优.故障排查的文章,自己也写了一篇< Java调优经验谈 >.接着此篇文章,其实一直打算写写一些常用调优工具以及它们的惯常用法的.后来在http://jav ...
- jdk自带监控程序jvisualvm的使用
监控小程序的配置 生产环境tomcat的配置 编辑应用所在的tomcat服务器下的bin目录下的catalina.sh文件,修改如下: 配置如下内容: export JAVA_OPTS="- ...
- 别再面向 for 循环编程了,JDK 自带的观察者模式就很香!
大家好,你还在面向 for 循环编程吗? 还有谁不会用观察者模式吗? 本篇栈长带来<观察者模式>理论及实战- 什么是观察者模式? 观察者模式(Observer Pattern)定义了对象间 ...
随机推荐
- POJ-1953 World Cup Noise(线性动规)
World Cup Noise Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16374 Accepted: 8097 Desc ...
- MySQL在windows下的noinstall安装
1.解压mysql zip软件包 2.配置环境变量 3.修改配置文件my_default.ini添加如下: [mysqld] basedir=D:\MySQL\MySQL Server 5.6(mys ...
- IO、NIO、AIO理解
摘要: 关于BIO和NIO的理解 最近大概看了ZooKeeper和Mina的源码发现都是用Java NIO实现的,所以有必要搞清楚什么是NIO.下面是我结合网络资料自己总结的,为了节约时间图示随便画的 ...
- css3的一个小demo(箭头hover变化)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue - vue-cli脚手架项目中组件的使用
在webpack-simple模板中,包括webpck模板.一个.vue文件就是一个组件. 为什么会这样呢?因为webpack干活了!webpack的将我们所有的资源文件进行打包.同时webpack还 ...
- celery消息的编码和序列化(转)
add by zhj: 原文讲的是序列化时的安全问题,不过,我关心的是怎样可以看到消息队列中的数据.下面是在broker中看到的消息,body是先用 body_encoding编码,然后用conten ...
- Android(三) 匹配屏幕密度
过去,程序员通常以像素为单位设计计算机用户界面.例如:图片大小为80×32像素.这样处理的问题在于,如果在一个dpi(每英寸点数) 高的显示器上运行该程序,则用户界面会显得很小.在有些情况下,用户界面 ...
- chown 命令
root@localhost ~]# .txt # 同时修改文件属主和属组 !chown 执行上一个chown命令
- C#基础笔记(第十一天)
1.复习字符串(1)字符串的不可变性(2)字符串的方法:1)Split() 分割 把字符串中不想要的内容分割掉 返回一个字符串类型的数组 可以添加StringSplitOption.RemoveEmp ...
- 12.预处理数据的方法总结(使用sklearn-preprocessing)
https://blog.csdn.net/sinat_33761963/article/details/53433799