刨根问底-ThreadLocal线程安全

孤人 提交于 2020-02-29 09:17:30


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

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

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

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

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

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

TreadLocal本身并不是一个线程,而是通过操作当前线程中的一个内部变量来达到与其他线程隔离的目的。之所以叫TdreadLocal,表示了其操作的对象时线程的一个本地变量。

现在看Thread代码:

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变量是否已经存在,如果不存在创建

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

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








易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!