因为nextHashCode被static修饰 , 所以每次new ThreadLocal()都会自增HASH_INCREMENT , 其值和斐波那契散列(Fibonacci)有关 , 主要目的是为了让哈希码能均匀的分布在2的n次方的数组里 。这也是为什么table的容量是2的n次方的一个原因 。
- 内存泄漏 & 弱引用 ThreadLocal使用不当可能会出现内存泄露 , 进而可能导致内存溢出** , 内存泄露:垃圾对象没有及时回收或无法回收 , 一般情况下是因为对象有错误的引用 , 导致内存浪费 , 这些垃圾越来越多可能会导致内存溢出 , 内存溢出:没有足够的内存提供申请者使用 。当然了 , 任何操作不当都会出现内存泄露或其他bug , 我们这里只谈论ThreadLocal 。回顾Thread、ThreadLocal、ThreadLocalMap的关系 。Thread.threadLocals引用ThreadLocalMap , 生命周期一致 。ThreadLocal定义ThreadLocalMapThreadLocalMap#Entry弱引用ThreadLocal 。我们通常说一个对象不被引用就会被gc回收 , 其实说的是强引用 。但弱引用对象是 , 不管有没有被引用都会被垃圾回收 。当一个Thread执行完 , 被销毁后 , Thread.threadLocals指向的ThreadLocalMap实例也会随之变为垃圾 , 当然它里面存放的Entity也会被回收 。这时是不会发生内存泄漏的 。发生内存泄漏一般是在线程池 , Thread生命周期比较长 , threadLocals引用一直存在 , 当其存放的ThreadLocal被回收(弱引用生命周期比较短)后 , 它对应的Entity就成了key==null的实例 , 依然不会被回收 。如果此Entity一直不被get()、set()、remove()它就一直不会被回收 , 也就发生了内存泄漏 。通常在使用完ThreadLocal都会调用它的remove() 。补充:在ThreadLocal的get、set的时候 , 都会检查当前Entity的key是否为null , 如果是null就把Entity释放掉 , 被垃圾回收 。
- 线程安全 , 包裹线程不安全的工具类 , 比如java.text.SimpleDateFormat类 , 当然jdk1.8已经给出了对应的线程安全的类java.time.format.DateTimeFormatter
- 线程隔离 , 比如数据库连接管理、Session管理、mdc日志追踪等 。
//接口请求时先走filterpublic boolean checkUserLogin(String token){ UserDTO user = getUserByToken(token); ContextUtil.setUserId(user.getId());}public class ContextUtil { private static ThreadLocal<String> userIdHolder = new ThreadLocal(); //存储userid public static void setUserId(String userId) { userIdHolder.set(userId); } public static String getUserId() { return (String)userIdHolder.get(); }} //实际调用接口void invokeInterface(){ String userId = ContextUtil.getUserId(); .....}每一次接口请求都是一个线程 , 在校验接口合法后把userid存入ThreadLocal , 以备后续之用 。总结我们通过源码 , 对ThreadLocal的原理和应用作了深入讲解 。当然本人能力一般 , 水平有限 , 难免有些谬误 。还请各位多担待 , 欢迎指正 。有反馈才有进步 。
【ThreadLocal原理及使用场景大揭秘】
推荐阅读
- 绿茶有多少茶叶种类,特征描述其绿茶新旧以及高山平底绿茶
- Springboot——自动配置原理
- 漫话三国茶事,三国晋朝的茶发展及文化
- 百合绿茶介绍,麦冬百合甘草茶制作及功效介绍
- 白茶的白毫是怎么回事,白茶的种类及基本制作工艺先容
- 灵芝茶功效及作用介绍,红菊花茶的功效与作用
- 绿茶制作及种类先容,茉莉花茶的基本先容
- 2022年杭州亚运会场馆建设进度?2022杭州亚运会项目及场地_1
- 2021苏锡常镇高三二模语文作文范文?2021届苏锡常高三二模作文题及范文_1
- 包种茶历史发展情况,绿杨春茶叶的历史渊源及发展
