Java并发 -- ThreadLocal模式
并发问题
- 多个线程同时读写同一个共享变量会存在并发问题
- Immutability模式和Copy-on-Write模式,突破的是写
- ThreadLocal模式,突破的是共享变量
ThreadLocal的使用
线程ID
1 | public class ThreadLocalId { |
SimpleDateFormat
1 | public class SafeDateFormat { |
ThreadLocal的工作原理
1 | public class Thread implements Runnable { |
- ThreadLocal仅仅是一个代理工具类,内部并不持有任何与线程相关的数据(存储在Thread里面)
- 不容易产生内存泄露,Thread持有ThreadLocalMap,而ThreadLocalMap对ThreadLocal的引用是弱引用
- 只要Thread被回收,那么ThreadLocalMap就能被回收
- 在线程池中使用ThreadLocal也有可能会导致内存泄露
- 因为线程池中线程的存活时间太长了,往往与程序同生共死
- 意味着Thread持有的ThreadLocalMap一直都不会被回收
- 可以通过try/finally手动释放
1 | private static final ExecutorService pool = Executors.newFixedThreadPool(1); |
InheritableThreadLocal
- 通过ThreadLocal创建的线程变量,其子线程是无法继承的,如果需要继承,则采用InheritableThreadLocal
- 不建议在线程池中使用InheritableThreadLocal
- 一方面,InheritableThreadLocal具有和ThreadLocal相同的缺点,可能会导致内存泄露
- 另一方面,线程池中的线程创建是动态的,容易导致继承关系错乱
- 如果业务逻辑依赖InheritableThreadLocal,有可能导致业务逻辑计算错误,比内存泄露更致命
参考资料
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.