刨根问底-ThreadLocal线程安全


一、线程安全,值得是在多线程环境先,一个类在执行某个方法时,对类的内部实例变量的访问时安全的。所以,对于下面列出来的2类变量,不存在任何线程安全的说法: java

(1)方法签名中的任何参数变量 安全

(2)处于方法内部的局部变量 多线程

线程安全针对于类内部的全局变量 并发

二、java.lang.ThreadLocal类是jdk提供一种解决多线程并发问题方案。 this

ThreadLocal类在维护变量时,实际使用了当前线程Thread中的一个叫作ThreadLocalMap的独立副本,每一个线程能够独立修改属于本身的副本而不会相互影响,从而隔离了线程和线程,避免了线程访问实例变量发生冲突的问题。 spa

TreadLocal自己并非一个线程,而是经过操做当前线程中的一个内部变量来达到与其余线程隔离的目的。之因此叫TdreadLocal,表示了其操做的对象时线程的一个本地变量。 线程

如今看Thread代码: code

public
class Thread implements Runnable {
ThreadLocal.ThreadLocalMap threadLocals = null;
}
ThreadLocalMap跟随者当前的线程而存在。不用的线程Thread,拥有不一样的ThreadLocalMap的本地实例变量,这就是副本的含义。

ThreadLocal是如何操做ThreadLocalMAP的 对象

public class ThreadLocal<T> {
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }
 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 getMap(Thread t) {
        return t.threadLocals;
    }
 void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }
ThreadLocalMap变量属于线程的内部属性,不一样的线程拥有彻底不一样的ThreadLocalMap变量

线程中的ThreadLocalMap变量的值是在ThreadLocal对象进行set和get操做时建立的,在建立以前首先检查当前的线程中的ThreadLocalMap变量是否已经存在,若是不存在建立 get

使用当前线程的ThreadLocalMap的关键在于使用当前的ThreadLocal的实例做为key进行存储。同一个线程中,不一样的ThreadLocal实例操做的对象之间相互隔离。

上面内容参考《struts2技术内幕》

相关文章
相关标签/搜索