最近在分析一潜在内存泄露问题的时候,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比较总结的更多相关文章

  1. 深度揭秘Netty中的FastThreadLocal为什么比ThreadLocal效率更高?

    阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...

  2. JDK自带线程池学习

    JDK自带线程池 线程池的状态 线程有如下状态 RUNNING状态:Accept new tasks and process queued tasks SHUTDOWN状态:Don't accept ...

  3. JDK自带的日志Logging

    OK,现在我们来研究下JDK自带的日志Logger. 从jdk1.4起,JDK开始自带一套日志系统.JDK Logger最大的优点就是不需要任何类库的支持,只要有Java的运行环境就可以使用. 相对于 ...

  4. JDK 自带的观察者模式源码分析以及和自定义实现的取舍

    前言 总的结论就是:不推荐使用JDK自带的观察者API,而是自定义实现,但是可以借鉴其好的思想. java.util.Observer 接口源码分析 该接口十分简单,是各个观察者需要实现的接口 pac ...

  5. [转]JDK自带工具之问题排查场景示例

    最近看到了大量关于java性能调优.故障排查的文章,自己也写了一篇Java调优经验谈.接着此篇文章,其实一直打算写写一些常用调优工具以及它们的惯常用法的.后来在http://java-performa ...

  6. 011 - JDK自带的性能监控工具

      一.概要: jps -l 查看现有的java进程 jps -l 显示所有正在运行的java进程id   jstack 查看Java线程      jstack -l pid; 做thread du ...

  7. JDK自带工具之问题排查场景示例

    最近看到了大量关于java性能调优.故障排查的文章,自己也写了一篇< Java调优经验谈 >.接着此篇文章,其实一直打算写写一些常用调优工具以及它们的惯常用法的.后来在http://jav ...

  8. jdk自带监控程序jvisualvm的使用

    监控小程序的配置 生产环境tomcat的配置 编辑应用所在的tomcat服务器下的bin目录下的catalina.sh文件,修改如下: 配置如下内容: export JAVA_OPTS="- ...

  9. 别再面向 for 循环编程了,JDK 自带的观察者模式就很香!

    大家好,你还在面向 for 循环编程吗? 还有谁不会用观察者模式吗? 本篇栈长带来<观察者模式>理论及实战- 什么是观察者模式? 观察者模式(Observer Pattern)定义了对象间 ...

随机推荐

  1. Linux系统下便捷使用中国知网的方式

    https://blog.csdn.net/mowangajimide/article/details/54144379

  2. 【转】Ant与Ivy的安装

    一.简介 Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.更多介绍 Apache Ivy,是一个管理项目依赖的工具.更多介绍请 ...

  3. 2018/03/09 每日一学PHP 之 require_once require include include_once 包含文件的区别

    require_once require include include_once 方法的区别 对于包含文件来说,如果只是使用框架来说的话,应该会很少碰到,因为框架底层对于文件的引用等做了很好的封装, ...

  4. 第二课 eclipse安装

    下载并解压到C:\Program Files\eclipse 目录情况如图所示:

  5. 前端 html input标签 disable 属性

    该属性只要出现在标签中,表示禁用该控件 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  6. spring boot上传 下载图片。

    https://blog.csdn.net/a625013/article/details/52414470 build.gradle buildscript { repositories { mav ...

  7. poj3468A Simple Problem with Integers(线段树的区域更新)

    http://poj.org/problem?id=3468 真心觉得这题坑死我了,一直错,怎么改也没戏,最后tjj把q[rt].lz改成了long long 就对了,真心坑啊. 线段树的区域更新. ...

  8. PHP高并发和大流量的解决方案

    第一个要说的就是数据库,首先要有一个很好的架构,查询尽量不用* 避免相关子查询 给经常查询的添加索引 用排序来取代非顺序存取,如果条件允许 ,一般MySQL服务器最好安装在Linux操作系统中 .关于 ...

  9. Java序列化总结

    什么是序列化? 序列化是将对象的状态信息转化为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后可以通过存储区中读取或反序列化对象的状态重新创建对象. 为什么要序 ...

  10. ReactNative前端开发者

    ReactNative前端开发者 文档版本0.0.2 Author: Necfol 说明: 本文档用于指导前端React Native的开发,如需开发其他其他框架应用,不适用本文档 前期准备 Reac ...