码迷,mamicode.com
首页 > 编程语言 > 详细

Java中ThreadLocal的深入理解

时间:2016-07-15 23:58:05      阅读:457      评论:0      收藏:0      [点我收藏+]

标签:

官方对ThreadLocal的描述:

  "该类提供了线程局部(thread-local)变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其get或set方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal实例通常是类中的private static字段,它们希望将状态与某一个线程(例如,用户ID或事物ID)相关联。"

《Thinking in Java》中的描述:

  防止任务在共享资源上产生冲突的第二种方式是根除对变量的共享。线程本地存储是一种自动化机制,可以为使用变量的每个不同的线程都创建不同的存储。因此,如果你有5个线程都要使用变量x所表示的对象,那线程本地存储就会生成5个用于x的不同的存储块。主要是,它们使得你可以将状态与线程关联起来。

三个要点:

  1.每个线程都有自己的局部变量

    每个线程都有一个独立于其它线程的上下文来保存这个变量,一个线程的本地变量对其它线程是不可见的。

  2.独立于变量的初始化副本

    ThreadLocal可以给一个初始值,而每个线程都会获得这个初始化值的一个副本,这样才能保证不同的线程都有一份拷贝。

  3.状态与某一个线程相关联

    ThreadLocal不是用于解决共享变量的问题的,不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制,就像《Thinking in  Java》中描述的那样:”它们使得你可以将状态与线程关联起来。“理解这点对正确使用ThreadLocal至关重要。

源码举例:

技术分享

  从输出的结果可以看出,五个线程处理自己的本地变量值。

技术分享

  而这个测试的结果,并没有相同。这是因为实例为对象,所以初始值为一个对象的引用,那么五个线程的副本就是这个对象的引用的副本,也就是说这些引用还是指向同一个对象,所以就出现了这种情况。

源码分析:

  get() :

 1 public T get() {
 2         //获取当前执行线程
 3         Thread t = Thread.currentThread();
 4         //取得当前线程的ThreadLocalMap实例
 5         ThreadLocalMap map = getMap(t);
 6         //如果map不为空,说明该线程已经有了一个ThreadLocalMap实例
 7         if (map != null) {
 8             //map中保存线程的所有的线程本地变量,我们要去查找当前线程本地变量
 9             ThreadLocalMap.Entry e = map.getEntry(this);
10             //如果当前线程本地变量存在这个map中,则返回其对应的值
11             if (e != null)
12                 return (T)e.value;
13         }
14         //如果map不存在或者map中不存在当前线程本地变量,返回初始值
15         return setInitialValue();
16 }

  set() :

 1 public void set(T value) {
 2         Thread t = Thread.currentThread();
 3         ThreadLocalMap map = getMap(t);
 4 
 5         if (map != null)
 6             map.set(this, value);
 7         //说明线程第一次使用线程本地变量(注意这里的第一次含义)
 8         else
 9             createMap(t, value);
10 }

       这里注意,ThreadLocal中是有一个Map,但这个Map不是我们平时使用的Map,而是ThreadLocalMap,ThreadLocalMap是ThreadLocal的一个内部类,不对外使用的。当使用ThreadLocal存值时,首先是获取到当前线程对象,然后获取到当前线程本地变量Map,最后将当前使用的ThreadLocal和传入的值放到Map中,也就是说ThreadLocalMap中存的值是[ThreadLocal对象, 存放的值],这样做的好处是,每个线程都对应一个本地变量的Map,所以一个线程可以存在多个线程本地变量

 

Java中ThreadLocal的深入理解

标签:

原文地址:http://www.cnblogs.com/zhengbin/p/5674638.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!