ThreadLocal:减少线程之间的共享

解决并发问题最简单的方案就是减少共享,JAVA提供了一个简单的工具类即ThreadLocal,我们会用他来保存线程之间独立存在的变量,比如springmvc中,我们每个请求特有的一些属性。

ThreadLocal的设计

在设计上JAVA的Thread内部类会持有一个ThreadLocalMap的对象threadLocals,Map的结构(ThreadLocal,Value),其中ThreadLocal是弱引用。
这么做的设计有俩点:

  1. 因为ThreadLocal对象和线程的声明周期息息相关,从数据的亲原性来讲,由Thread对象管理更为合适
  2. 防止内存泄露,因为ThreadLocal内部持有线程和Value的对应关系,当线程声明结束后,ThreadLocal中的Thread对象不会主动释放。从而造成内存泄露

ThreadLocal的内存泄露

在线程池中,Thread的生命周期往往很长,而因为ThreadLocalMap对于ThreadLocal是软引用,所以当ThreadLocal没有引用时候会被释放掉,但是Value确是强引用,所以会造成ThreadLocal释放掉了,但是Value没法释放导致内存泄露

解决方法:手动释放

InheritableThreadLocal继承性

因为ThreadLocal是线程不共享的,所以如果线程在创建一个子线程是看不到主线程ThreadLocal对象的值的,为了让子线程能看到父类线程提供InheritableThreadLocal,但是不建议使用,因为往往会导致子线程修改了值引起主线程的逻辑混乱。