30线程本地存储模式
没有共享,就没有伤害
1 | static class SafeDateFormat { |
ThreadLocal的工作原理
ThreadLocalMap,key:WeakReference
ThreadLocal与内存泄露
线程池中线程的存活时间长,往往和程序同生共死的,则Thread持有的ThreadLocalMap一直都不会被回收。
ThreadLocalMap中的Entry对ThreadLocal是弱引用(WeakReference),所以只要ThreadLocal结束了自己的生命周期是可以被回收掉的。但是Entry中的Value却是被Entry强引用的,所以即便Value的生命周期结束了,Value也是无法被回收的,从而导致内存泄露。
解决办法:手动释放
1 | ExecutorService es; |
InheritableThreadLocal与继承性
通过ThreadLocal创建的线程变量,其子线程是无法继承的(无法访问)
不建议使用:线程池中线程的创建是动态的,很容易导致继承关系错乱,若业务逻辑依赖InheritableThreadLocal,那么很可能导致业务逻辑计算错误。
问题
实际工作中,有很多平台型的技术方案都是采用ThreadLocal来传递一些上下文信息,例如Spring使用ThreadLocal来传递事务信息。我们曾经说过,异步编程已经很成熟了,那你觉得在异步场景中,是否可以使用Spring的事务管理器呢?
???