ThreadLocal
参考敖丙
原理
- Thread类里维护的ThreadLocals Map结构。
每个Thread都有一个Map,key是ThreadLocal,valve是你传的值。这个Map底层是拿数组实现的,没有链表,hash冲突时会向后面的桶找空位置。
用途
- 非常多的地方都提到了SimpleDateFormat,内部维护了一个Calendar,parse()方法会先调Calendar.clear(),再调Calendar.add()。多线程操作不安全。线程池加上ThreadLocal包装SimpleDataFormat,再调用initialValue让每个线程有一个SimpleDataFormat的副本,从而解决了线程安全的问题,也提高了性能。
- cookie、session等数据隔离。
before
void work(User user) {
getInfo(user);
checkInfo(user);
setSomeThing(user);
log(user);
}
then
void work(User user) {
try{
threadLocalUser.set(user);
getInfo();
checkInfo();
setSomeThing();
log();
} finally {
threadLocalUser.remove();
}
}
问题
- 内存泄露,原因是Thread的那个Map的Entry的key是对Threadlocal对象的若引用,如果别的地方不再强引用Threadlocal对象时,一旦GC,这个对象会被回收,Entry的key为null,valve内存泄漏永远不会被回收,因此在使用完ThreadLocal完成必须remove掉。