多线程

92 阅读1分钟

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);
   // 他们内部  User u = threadLocalUser.get(); 就好了
    getInfo();
    checkInfo();
    setSomeThing();
    log();
    } finally {
     threadLocalUser.remove();
    }
}

  • 框架使用 spring管理事务

问题

  • 内存泄露,原因是Thread的那个Map的Entry的key是对Threadlocal对象的若引用,如果别的地方不再强引用Threadlocal对象时,一旦GC,这个对象会被回收,Entry的key为null,valve内存泄漏永远不会被回收,因此在使用完ThreadLocal完成必须remove掉。