这篇文章会从三个方面来说说Threadlocal
- ThreadLocal用在什么地方?
- ThreadLocal的get/set源码分析!
- ThreadLocal的使用方法!
1、ThreadLocal用在什么地方?
1.1)保存线程上下文信息,在任意需要的地方可以获取。
例如Spring的事务管理,用ThreadLocal存储Connection,从而各个DAO可以获取同一Connection,可以进行事务回滚,提交等操作
1.2)线程安全的,避免某些情况需要考虑线程安全必须同步带来的性能损失。
每个线程往ThreadLocal中读写数据是线程隔离,互相之间不会影响的,所以ThreadLocal无法解决共享对象的更新问题!
我们来看一段代码:
如上图,主线程中那不到one/two线程放进去的值。那么是如何实现的呢?我们来看看源码是如何实现的
2、ThreadLocal的get/set源码分析!
这两个方法中会首先获取到当前线程,在进行操作,我们知道Thread中有一个ThreadLocalMap的成员变量,他们的关系如下:
所以看似共用一个threadLocal,但其实每个线程又有一个自己的副本 threadlocalMap
注意这里,一个ThreadLocal只能存储一个Object对象,如果需要存储多个Object对象那么就需要多个ThreadLocal!!!
3、ThreadLocal的使用方法!
我们可以看到Entry是继承了一个弱引用,当仅仅只有ThreadLocalMap中的Entry的key指向ThreadLocal的时候,ThreadLocal会进行回收的!!!
ThreadLocal被垃圾回收后,在ThreadLocalMap里对应的Entry的键值会变成null,但是Entry是强引用,那么Entry里面存储的Object,并没有办法进行回收,所以ThreadLocalMap 做了一些额外的回收工作。
所以最佳写法应该为: