Java中的ThreadLocal对象

1.什么是ThreadLocal

    根据JDK文档中的解释:ThreadLocal的作用是提供线程内的局部变量,这种变量在多线程环境下访问时能够保证各个线程里变量的独立性。

    从这里可以看出,引入ThreadLocal的初衷是为了提供线程内的局部变量,而不是为了解决共享对象的多线程访问问题。实际上,ThreadLocal根本就不能解决共享对象的多线程访问问题。


2.ThreadLocal实现原理

    每个线程中可以持有很多个ThreadLocal对象,这些对象通过hash后存储在Thread的ThreadLocalMap中,其中的Key为ThreadLocal对象,value为该对象在本线程中的一个副本。用图表示如下:


    从图中可以看出,ThreadLocal本身并不存储value值,只是作为key在ThreadLocalMap中索引value值

3.ThreadLocal是否会造成内存泄露?

     每个Thread含有的ThreadLocalMap中的Key为ThreadLocal变量的弱引用,如果一个ThreadLocal变量没有外部强引用来引用它,那么它在JVM下一次GC的时候会被垃圾回收掉,这时候,Map中就存在了key为NULL的value,这个value无法被访问。如果当前线程再迟迟不结束的话(例如当前线程在一个线程池中),那么value所指向的对象可能永远无法释放,也即不能被回收,造成内存泄露。

     ThreadLocalMap的设计者很显然也想到了这个问题,所以其在每一次对ThreadLocalMap的set,get,remove等操作中,都会清除Map中key为null的Entry。因此,ThreadLocal一般是不会存在内存泄露风险的。

     但是,将清除NULL对象的工作交给别人,并不是一个明智的选择,所以聪明的你,在Thread中使用完ThreadLocal对象后,一定要记得调用ThreadLocal的remove方法,进行手动清除。

4.示例代码

[java]  view plain  copy
  1. /** 
  2.  * JDK Version:1.8 
  3.  */  
  4. public class ThreadLocalTest {  
  5.     private static final ThreadLocal<Integer> local = ThreadLocal.withInitial(()->0);  
  6.     public static void main(String[] args) throws InterruptedException {  
  7.         for(int i = 0; i < 10;i += 3){  
  8.             new MyThread(i).start();  
  9.         }  
  10.     }  
  11.   
  12.     static class MyThread extends Thread{  
  13.         private int end;  
  14.   
  15.         public MyThread(int end) {  
  16.             this.end = end;  
  17.         }  
  18.   
  19.         @Override  
  20.         public void run() {  
  21.             System.out.println(Thread.currentThread().getName() + " start, local = " + local.get());  
  22.             for(int i = 0; i < end;i++){  
  23.                 local.set(local.get() + i); //计算(end+1)*end/2的值  
  24.             }  
  25.             System.out.println(Thread.currentThread().getName() + " start, local = " + local.get());  
  26.         }  
  27.     }  
  28. }  
运行结果如下:
Thread-0 start, local = 0
Thread-2 start, local = 0
Thread-1 start, local = 0
Thread-2 start, local = 21
Thread-3 start, local = 0
Thread-0 start, local = 0
Thread-3 start, local = 45
Thread-1 start, local = 6
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值