您的位置:首页 > 编程语言 > Java开发

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算法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: