java中threadlocal的理解


java中threadlocal的理解


一、threadlocal的生命周期和ThreadLocalMap的生命周期

可以吧TreadLocal看做是一个map来使用,只不过这个map是指向当前线程中的threadLocals(ThreadLocalMap.class),这个threadLocals采用懒汉单例在一个线程中是唯一的。

Thread中的threadLocals属性,存放的是当前线程在不同TreadLocal实例中的值ThreadLocalMap<TreadLocal,T>

 

1 public void set(T value) {
2      Thread t = Thread.currentThread();
3      ThreadLocalMap map = getMap(t);//return t.threadLocals;这里表示只有一个ThreadLocalMap副本
4      if (map != null)//采用懒汉模式
5          map.set(this, value);
6      else
7          createMap(t, value);//t.threadLocals = new ThreadLocalMap(this, firstValue);
8  }

 

可以通过查看当前线程中的threadLocals变量,来看当前线程持有多少个threadLocal,以及存的值。

ThreadLocalMap实例的生命周期随着线程的结束而结束,因为ThreadLocalMap实例的唯一引用只存在当前线程中。ThreadLocal的生命周期,需要gc来决定,因为他的引用可能存在于多个线程中,此引用为弱引用。

弱引用的存在,导致可能内存泄露。当threadlocal=null,没有任何强引用实例指向threadLocals中的key本来指向的threadlocal实例,gc回收threadlocal,导致val永远不会被释放。采用以下代码来取代=null的操作,用remove函数来清除,threadLocals。

1 ThreadLocal local1 = new ThreadLocal();
2 local.remove();

 

 

 


二、ThreadLocal的作用

对于那些需要数据隔离,可以用ThreadLocal。

对于一个线程中的一个ThreadLocal只能存一个T类型的数据。(T为泛型)

ThreadLocal是线程安全的,所以可以用来封装线程不安全的实例,不同线程之间新创建实例,保证线程安全。(另一种模式就是单例模式。)


三、示例

比较经典的例子就是github中的PageHelper中保存Page信息的时候使用了ThreadLocal。考虑到数据的同步,已经一个线程只会顺序执行sql语句。

1 protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal();
2 protected static void setLocalPage(Page page) {
3         LOCAL_PAGE.set(page);
4 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM