文章字数:455,阅读全文大约需要1分钟
ThreadLocal可以在多线程下实现各个线程的数据隔离
存储原理
直接看ThreadLocal的get()方法
1 | public T get() { |
可以看出
- 数据是使用
ThreadLocalMap存储的 ThreadLocalMap是存放在线程对象上,所以可以保证线程之间的独立
再看map.getEntry(this)这句话调用的方法
1 | private Entry getEntry(ThreadLocal<?> key) { |
可以看出
- 存放在线程的
Map通过ThreadLocal对象的threadLocalHashCode获取具体是那个对象 ThreadLocal对象只是获取值的key真正的数据保存在Thread线程对象上
弱引用
存储数据的ThreadLocalMap里可以看到
1 | static class Entry extends WeakReference<ThreadLocal<?>> { |
entry的键是被弱引用包裹的,即GC的时候如果没有强引用则会被直接清理。- 即外面的
ThreadLocal如果被赋值为null,即取消对象的强引用。不会因为ThreadLocalMap里面还有强引用而无法被清除 - 但是
value还是强引用,所以如果不remove元素值还是会造成内存泄露
内存泄露的问题
因为只有键有加弱引用,可以使ThreadLocal外界无强引用时直接被GC。但是key还是强引用,所以需要手动remove
其它问题
- 虽然
ThreadLocal是随着线程消亡,但如果使用线程池,那么就会被复用。因为线程池的原理就是复用线程