Java ThreadLocal 是如何发挥作用的
2018-02-27 17:36
603 查看
Java ThreadLocal 是如何发挥作用的。
首先插入一个ThreadLocal的使用场景以及用法的链接,这个链接里讲的很通畅。看完之后我们分析下源码:
以下源码来自JDK1.8
Thread.java源码
public class Thread implements Runnable { //... //Thread中包含了一个ThreadLocal.ThreadLocalMap局部变量。ThreadLocalMap是ThreadLocal的内部类,维护了一个Hash map /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null; //.. //与threadLocals变量相关的方法有以下: //该方法就是用于在线程退出时,清理线程资源的。可以看到将threadLocals置为了null /** * This method is called by the system to give a Thread * a chance to clean up before it actually exits. */ private void exit() { if (group != null) { group.threadTerminated(this); group = null; } /* Aggressively null out all reference fields: see bug 4006245 */ target = null; /* Speed the release of some of these resources */ threadLocals = null; inheritableThreadLocals = null; inheritedAccessControlContext = null; blocker = null; uncaughtExceptionHandler = null; }
ThreadLocal.java部分源码
//与threadLocals变量相关的方法有以下: /** * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; //返回线程t中的成员变量threadLocals } /** * Create the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * * @param t the current thread * @param firstValue value for the initial entry of the map */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } //ThreadLocal的get、set方法 /** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread();//从这里可以看到,如果在一个线程中调用了该方法之后,会获取到该线程(当前线程) ThreadLocalMap map = getMap(t); //并作为变量传入getMap()方法中。所以最终得的map便是当前线程中的threadLocals。 if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); //ThreadLocalMap中key是ThreadLocal变量(this),value是 if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); //该方法设置当前线程的ThreadLocalMap中key为this,value为null。如果ThreadLocalMap为空则新建然后再设置 } /** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
总结一下就是,每个线程中都有一个ThreadLocalMap来保存多个ThreadLocal变量。key就是ThreadLocal变量。每次set/get操作都是对应到当前线程的map上。达到了隔离的效果。当然了ThreadLocalMap并不是implement Map的,其内部也不是用HashMap实现的,是另外一种hash算法。
相关文章推荐
- 第1章 Java基本概念及环境配置——FAQ1.07 什么是JVM?有什么作用?工作机制如何?
- 包的学习5:如何发挥包的作用
- 如何更好地发挥日志功能来推进java企业开过程
- 如何使过程改进发挥作用
- C#委托的妙文,让你知道如何发挥委托的作用
- 什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。
- 如何发挥飞鸽传书系统作用
- Java中ThreadLocal类的作用以及实现原理-----hibernate的连接池就是用ThreadLocal实现的
- Java多线程有哪几种实现方式? Java中的类如何保证线程安全? 请说明ThreadLocal的用法和适用场景(面试题)
- 如何让布尔变量在过程,函数,触发器以及匿名块中发挥作用
- 如何最大限度发挥EVSSL证书的作用
- 如何最大限度发挥EVSSL证书的作用
- 【ThinkingInJava】15、如何让Scanner作用到一个类上
- 如何让Redis发挥更大作用?
- C#委托的妙文,让你知道如何发挥委托的作用
- java5核心基础之泛型(3)-泛型作用于编译阶段-如何将String对象传入Integer类型的泛型对象中?
- [转载]C#委托的妙文,让你知道如何发挥委托的作用
- 如何让博客发挥最大作用
- 项目管理--项目经理如何发挥自己最大的作用
- C#委托的妙文,让你知道如何发挥委托的作用