threadLocal的分享

本文分析了一款应用中书城首页广告解锁书籍的Free标识显示不稳定的问题。通过对线程池和ThreadLocal的深入研究,发现了InheritableThreadLocal在多线程环境下导致的数据一致性问题,并提出了解决方案。

问题描述:

1、书城首页的书明明是广告解锁的,但是没有free标识,经过多次接口请求得出结论,相同的请求参数,有时会展示出free标识,有时不会展示free标识

问题分析:

1、长时间分析也没有得出结论,因为通过redis和mongodb的查询,所有步骤都能查出对应的数据(该有free的就应该有,没有的就没有),(其实可以使用其他工具排查数据的,例如:arthas,但是当时线上系统没有这个工具)

2、无意发现在线程池的execute方法中使用了MediaHolder这个类,这个类中使用了InheritableThreadLocal,然后就想到线程池中使用ThreadLocal会有些问题

解决:

1、在线程池中重新设置该值,在功能结束时,注销threadLocal

2、以方法的入参形式传递下去,但是这个功能使用media的地方嵌套层次比较深,需要修改的方法太多,最后还是选用第一种方式

3、建议:在线程池中如果使用threadLocal的话,最好在线程池外获取,并在线程池内的方法中重新赋值

原理:

  1. 问题引出:media和media2的值一样么?不一定

1、MediaHolder中使用的ThreadLocal是inheritable类型的(可继承的)

2、也就是说使用了可继承的threadLocal会让线程池中的Thread会复制InheritableThreadLocal,

线程初始化时:

3、使用get方法时,实际使用的是InheritableThreadLocal的get方法,而该类是继承ThreadLocal,重写了getMap方法,返回的ThreadLocalMap是inheritableThreadLocals属性。

注:ThreadLocal中有两个属性的类型是ThreadLocalMap类型:threadLocals和inheritableThreadLocals

4、线程池中如果使用threadLocal的get方法时和线程池外获取的结果可能不一样,

5、线程池创建work,work是一个线程,不断的获取任务,并执行任务,也就是说同一个work可以执行多个任务且任务的ThreadLocal都是一样的。

下图是创建核心worker,其中workQueue.offer(command)就是将任务放到队列中,后续可能会启动非核心work。

在addWorker()方法中有t.start()方法就是开始执行这个线程

下图是核心worker工作的开始

下图是worker不停获取任务方式:1、从firstTask中获取任务,2、从任务队列中获取任务

<think> 嗯,用户希望获取一些Java技术分享的主题内容。参考提供的引用资料,需要从基础、进阶、应用三个维度组织内容。 用户可能是Java初学者或有一定经验的开发者。引用[4]提到自学门槛提高,说明用户可能关注系统性学习路径;引用[3]强调实践技巧,暗示用户需要可落地的技术方案。 准备构建三层知识框架: 1. **基础核心**:引用[1][4]强调Java基础和集合框架,计划设计语法特性、集合优化等主题 2. **开发进阶**:引用[2][3]提及多线程和GUI开发痛点,考虑加入并发编程实战和界面设计原则 3. **行业应用**:引用[2]提到面试考察点,准备补充微服务和性能调优等工业级实践 特别注意引用[3]指出的"变量final声明"等细节技巧,会在分享内容中穿插这类实用建议。对于自学建议(引用[4]),将在最后补充学习路径说明。 为避免信息过载,每个主题控制在3-5个技术点,保持可操作性。技术深度参考引用[2]中"大牛总结"的标准,例如并发部分会包含CAS原理而不仅是synchronized用法。 最后生成的分享内容采用分层结构,帮助用户根据自身水平选择学习重点。相关问题设计将覆盖知识盲区检测(如异常处理误区)和技术演进(如新版本特性)。 </think>以下是精心整理的Java技术分享内容框架,涵盖核心知识点与实践技巧,结合行业需求设计: --- ### 一、Java核心技术专题 1. **Java内存模型与GC调优** - JVM内存分区:堆/栈/方法区 - GC算法对比:CMS vs G1 vs ZGC - 实战:`jstat`+`VisualVM`内存泄漏排查 $$ GC\ \text{停顿时间} = \frac{\text{存活对象数量}}{\text{回收速率}} $$ 2. **并发编程深度解析** - 线程池核心参数:`corePoolSize`/`workQueue`/`RejectedExecutionHandler` - 锁优化:偏向锁→轻量级锁→重量级锁升级过程 - **案例**:高并发场景下的`ThreadLocal`内存泄漏防范[^3] --- ### 二、现代Java开发实践 ```java // Java17新特性:模式匹配简化代码 if (obj instanceof String s) { System.out.println(s.toUpperCase()); // 直接使用类型转换后的s } ``` 3. **微服务架构关键点** - 服务通信:OpenFeign动态代理实现原理 - 熔断降级:Hystrix滑动窗口算法 $$ \text{失败率} = \frac{\text{最近10秒失败请求}}{\text{总请求}} \times 100\% $$ - 配置中心:Apollo实时推送机制 4. **高效代码设计规范** - 设计模式应用场景: - 工厂模式解决对象创建耦合 - 策略模式替代复杂`if-else`[^3] - **强制规范**:所有方法参数用`final`修饰(防止意外修改)[^3] --- ### 三、性能优化专项 5. **数据库交互优化** | 方案 | 吞吐量提升 | 适用场景 | |---------------------|------------|------------------| | 连接池配置 | 40%~60% | 高频短查询 | | 批量处理`addBatch()` | 3~5倍 | 数据导入 | | 二级缓存 | 10~30倍 | 读多写少业务 | 6. **JIT编译优化原理** - 方法内联:字节码→机器码转换过程 - 热点代码检测:基于计数器的触发机制 - 逃逸分析助力栈上分配 $$ \text{优化比} = \frac{\text{栈分配对象数}}{\text{总对象数}} $$ --- ### 四、开发效能提升 7. **持续交付流水线设计** ```mermaid graph LR A[代码提交] --> B(静态检查) B --> C{单元测试覆盖率>80%?} C -->|是| D[构建镜像] D --> E[灰度发布] ``` 8. **容器化实践要点** - Docker镜像分层:基础层+应用层 - JVM内存限制:`-XX:MaxRAMPercentage=75.0` - 调试技巧:`jattach <pid> load instrument false jdwp=5005` --- > **自学建议**:根据引用[4],自学需重点关注: > 1. 建立系统知识图谱(如Java集合框架全景图) > 2. 每阶段完成**可验证的项目**(如实现简易RPC框架) > 3. 加入技术社区参与Code Review[^4]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值