这篇文章会从三个方面来说说Threadlocal

  • ThreadLocal用在什么地方?
  • ThreadLocal的get/set源码分析!
  • ThreadLocal的使用方法!

1、ThreadLocal用在什么地方?

1.1)保存线程上下文信息,在任意需要的地方可以获取。
         例如Spring的事务管理,用ThreadLocal存储Connection,从而各个DAO可以获取同一Connection,可以进行事务回滚,提交等操作
1.2)线程安全的,避免某些情况需要考虑线程安全必须同步带来的性能损失。
         每个线程往ThreadLocal中读写数据是线程隔离,互相之间不会影响的,所以ThreadLocal无法解决共享对象的更新问题!

我们来看一段代码:

ThreadLocal 使用和原理

如上图,主线程中那不到one/two线程放进去的值。那么是如何实现的呢?我们来看看源码是如何实现的

 2、ThreadLocal的get/set源码分析!

ThreadLocal 使用和原理

ThreadLocal 使用和原理

这两个方法中会首先获取到当前线程,在进行操作,我们知道Thread中有一个ThreadLocalMap的成员变量,他们的关系如下:

ThreadLocal 使用和原理

所以看似共用一个threadLocal,但其实每个线程又有一个自己的副本 threadlocalMap

ThreadLocal 使用和原理

注意这里,一个ThreadLocal只能存储一个Object对象,如果需要存储多个Object对象那么就需要多个ThreadLocal!!!

ThreadLocal 使用和原理

3、ThreadLocal的使用方法!

ThreadLocal 使用和原理

我们可以看到Entry是继承了一个弱引用,当仅仅只有ThreadLocalMap中的Entry的key指向ThreadLocal的时候,ThreadLocal会进行回收的!!!

ThreadLocal被垃圾回收后,在ThreadLocalMap里对应的Entry的键值会变成null,但是Entry是强引用,那么Entry里面存储的Object,并没有办法进行回收,所以ThreadLocalMap 做了一些额外的回收工作。

ThreadLocal 使用和原理

所以最佳写法应该为:

ThreadLocal 使用和原理

 

相关文章: