当前位置:首页 > 开发 > 编程语言 > 多线程 > 正文

我对ThreadLocal的理解

发表于: 2013-11-04   作者:bylijinnan   来源:转载   浏览次数:
摘要: http://javarecipes.com/2012/07/11/understanding-the-concept-behind-threadlocal/ http://blog.csdn.net/qjyong/article/details/2158097 这两篇文章都认为ThreadLocal的实现原理说到底是一个Map<Thread currentThread, Obj
http://javarecipes.com/2012/07/11/understanding-the-concept-behind-threadlocal/
http://blog.csdn.net/qjyong/article/details/2158097

这两篇文章都认为ThreadLocal的实现原理说到底是一个Map<Thread currentThread, Object value>:
 
public class CustomThreadLocal {
 
    private static Map threadMap = new HashMap();
 
    public static void add(Object object) {
        threadMap.put(Thread.currentThread(), object);
    }
 
    public static void remove(Object object) {
        threadMap.remove(Thread.currentThread());
    }
 
    public static Object get() {
        return threadMap.get(Thread.currentThread());
    }
 
}


我认为, 这个观点只有一半是正确的。
ThreadLocal确实是通过Map来实现,但这个Map的key并不是Thread.curentThread,而是ThreadLocal的实例本身。

简单地说,ThreadLocal的关键的地方在下面两点:
1.同一线程内,把某值(假设为someValue)存储在ThreadLocal内,那么可以在本线程内的任意其他地方、任意其他时间获得这个值
2.对于其他线程来说,第1点里面的someValue是不可见的

这是怎么做到的呢?
这是通过“每一个线程,都持有一个ThreadLocal.ThreadLocalMap的实例”来实现的。

查看Thread源码,Thread有一个实例域:
ThreadLocal.ThreadLocalMap threadLocals = null;
而ThreadLocal.ThreadLocalMap就是一个Map。

查看ThreadLocal.ThreadLocalMap,发现它的key就是当前的ThreadLocal:
ThreadLocal.ThreadLocalMap的set方法:
private void set(ThreadLocal key, Object value) {
	/*......*/
}


再返回去看看ThreadLocal的set方法:
     public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }


可以清晰地看到,ThreadLocal.ThreadLocalMap的key就是this,也就是当前的ThreadLocal


举例:
class MyThreadLocalA {
    private static final ThreadLocal threadLocalInstanceA = new ThreadLocal();
    
    public static Object get() {
        return threadLocalInstanceA.get();
    }
    /*.....*/
}

class MyThreadLocalB {
    private static final ThreadLocal threadLocalInstanceB = new ThreadLocal();
    public static Object get() {
        return threadLocalInstanceB.get();
    }
    /*.....*/
}


假设有两个线程,分别是threadX和threadY
假设threadX访问MyThreadLocalA时,放入值"X_A",访问MyThreadLocalB时放入值"X_B"
假设threadY访问MyThreadLocalA时,放入值"Y_A",访问MyThreadLocalB时放入值"Y_B"

那么
threadX.threadLocals(我们称之为xMap)会是这样:
key 													value
---------------------------------------------
threadLocalInstanceA							X_A
threadLocalInstanceB							X_B


threadY.threadLocals(我们称之为yMap)会是这样:
key 													value
---------------------------------------------
threadLocalInstanceA							Y_A
threadLocalInstanceB							Y_B


那么在线程threadX内执行MyThreadLocalA.get(),得到的值就会是"X_A"。
具体流程:
MyThreadLocalA.get()
-->threadLocalInstanceA.get()
	 -->Thread.currentThread.threadLocals(也就是xMap)
		  -->xMap.getEntry(this)(这里的this就是threadLocalInstanceA)
			   -->得到"X_A"


其实过程很清晰。别人说的再多,还不如自己去看看源代码~   

我对ThreadLocal的理解

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序
概述 我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序
ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序
早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一
本文来自CSDN博客:http://blog.csdn.net/qjyong/archive/2008/03/08/2158097.aspx ThreadLocal是什
值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。AP
值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。AP
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号