选择依据
- 子线程继承父线程某些ThreadLocal变量:
- 选择
InheritableThreadLocal
。它会在创建子线程时,自动将父线程中InheritableThreadLocal
的值复制到子线程中。例如,在一个分布式跟踪系统中,父线程的跟踪ID需要被子线程继承以实现全链路跟踪,就可使用InheritableThreadLocal
。
- 子线程有完全独立的ThreadLocal变量:
- 选择
ThreadLocal
。ThreadLocal
为每个线程提供独立的变量副本,子线程创建时不会继承父线程ThreadLocal
的值。比如,在数据库连接管理中,每个线程需要有自己独立的数据库连接,使用ThreadLocal
可以避免线程间连接的干扰。
高并发场景优化思路及代码调整
- ThreadLocal优化:
- 内存泄漏问题:
- 思路:
ThreadLocal
使用不当可能导致内存泄漏,因为ThreadLocalMap
的Entry
以弱引用指向ThreadLocal
实例。如果外部对ThreadLocal
的强引用消失,而线程还在运行,Entry
中的value
不会被回收。
- 代码调整:在使用完
ThreadLocal
后,及时调用remove()
方法清理ThreadLocalMap
中的Entry
。例如:
ThreadLocal<String> threadLocal = new ThreadLocal<>();
try {
threadLocal.set("value");
// 业务逻辑
} finally {
threadLocal.remove();
}
- 性能优化:
- 思路:减少
ThreadLocal
实例的创建,对于相同用途的ThreadLocal
可以复用。
- 代码调整:将
ThreadLocal
定义为静态常量。例如:
private static final ThreadLocal<String> THREAD_LOCAL = ThreadLocal.withInitial(() -> "default value");
- InheritableThreadLocal优化:
- 减少不必要的继承:
- 思路:如果部分子线程不需要继承父线程
InheritableThreadLocal
的值,可在子线程创建前,通过remove()
方法移除相关InheritableThreadLocal
的值。
- 代码调整:
InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();
inheritableThreadLocal.set("parent value");
Thread childThread = new Thread(() -> {
inheritableThreadLocal.remove();
// 子线程业务逻辑,不继承父线程InheritableThreadLocal的值
});
childThread.start();
- 自定义传递逻辑:
- 思路:在复杂业务场景下,
InheritableThreadLocal
默认的复制逻辑可能不满足需求。可通过继承InheritableThreadLocal
并重写childValue
方法来自定义传递逻辑。
- 代码调整:
class CustomInheritableThreadLocal extends InheritableThreadLocal<String> {
@Override
protected String childValue(String parentValue) {
// 自定义子线程值的生成逻辑
return parentValue + "_child";
}
}
- 避免过多数据传递:
- 思路:
InheritableThreadLocal
传递数据可能带来额外开销,尽量只传递必要的数据。
- 代码调整:将多个相关数据封装成一个轻量级对象,通过
InheritableThreadLocal
传递该对象。例如:
class ContextData {
private String data1;
private int data2;
// 构造函数、getter和setter方法
}
InheritableThreadLocal<ContextData> contextThreadLocal = new InheritableThreadLocal<>();