ThreadLocal的使用以及坑

参考:https://www.cnblogs.com/yxysuanfa/p/7125761.html

 

做个总结:

1.正常情况:

ThreadLocal threadLocal = new ThreadLocal<>(),ThreadLocal 的构造函数接收的是一个泛型对象,可以是存储一个String,Map,Entity等对象,我们通过操作 threadLocal.set(t), threadLocal.get(), threadLocal.remove()方法,可以在线程内部维护一个对象,用来在整个线程的生命周期中作为数据总线传递参数。每个线程中存储的数据都是隔离的。其原理是:threadLocal.set(t)时,会将 ThreadLocal 对象本身 this 作为key(之所以用当前的 ThreadLocal 对象作为key,是因为一个线程执行的生命周期中,允许你创建很多的ThreadLocal对象,如ThreadLocal<会员信息对象>, ThreadLocal<订单详情对象>, ThreadLocal<产品详情对象>),泛型对象 t 作为 value 存储在 ThreadLocal.ThreadLocalMap 对象中,而 ThreadLocal.ThreadLocalMap 对象又是当前执行的线程对象 Thread 的一个成员属性,如此就保证了每个 ThreadLocal 中存储的数据都是基于线程隔离的。

2.需要注意有那些坑:

既然我们明白了 ThreadLocal.ThreadLocalMap 是当前执行的线程对象的成员属性,就应该知道其生命周期是和线程同步的。正常情况下,线程执行结束后出栈,等待被gc回收,生命周期正常结束是没有问题的。但需要注意的是:在线程池中,线程执行结束后如果不被释放,它的生命周期可能很长,会继续等待下一次执行任务。而使用 ThreadLocal 存储的泛型对象则会被线程在下一次执行时获取到里面的内容,此时存储的数据相当于是线程共享的。解决办法(最佳实践)是:无论何时,使用 ThreadLocal 传递参数都要有始有终,在线程执行结束时,手动调用 threadLocal.remove() 方法,删除 threadLocal.set(t) 时存放的数据,保证线程存储的数据是安全的。

你可能感兴趣的:(java基础)