ThreadLocal初解

ThreadLocal初解

简介

ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。

类ThreadLocal的主要作用是将数据放入当前线程对象中的Map(ThreadLocal.ThreadLocalMap)中,这个Map是Thread的实例变量。

类ThreadLocal自己不管理、不存储任何数据,他只是数据和Map之间的桥梁,用于将数据放入Map中。

public class ThreadLocalTest {

    private static ThreadLocal threadLocal = new ThreadLocal();

    public static void main(String[] args) throws InterruptedException {
        threadLocal.set("在main线程里放了一个值");
        Thread a = new Thread(new Runnable() {
            @Override
            public void run() {
                threadLocal.set("在a线程里放了一个值");
                System.out.println(threadLocal.get());
            }
        }, "a");
        a.start();
        a.join();
        System.out.println(threadLocal.get());
    }

}

在这里插入图片描述
threadLocals与inheritableThreadLocals的区别是inheritableThreadLocals是可以继承的Map,子线程可以继承父线程的Map值

在Thread对象中threadLocals对应的Map key为一个ThreadLocal对象,多个线程可以将同一个ThreadLocal对象作为key.

ThreadLocalMap解析

ThreadLocalMap是ThreadLocal类中的一个静态内部类是默认的包可见,使用一个Entry做个Map的键值,K为ThreadLocal,V是一个Object

        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
		//构造函数
		ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
            //初始一个大小为16的桶
            table = new Entry[INITIAL_CAPACITY];
            //通过key的threadLocalHashCode计算出桶中的位置
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            //初始化一个Entry
            table[i] = new Entry(firstKey, firstValue);
            //数量设置为1
            size = 1;
            setThreshold(INITIAL_CAPACITY);
        }
		//用于继承ThreadLocal的创建 在线程初始化过程中如果此线程是需要继承父线程的ThreadLocal值,则会间接调用此方法
		private ThreadLocalMap(ThreadLocalMap parentMap) {
            Entry[] parentTable = parentMap.table;
            int len = parentTable.length;
            setThreshold(len);
            table = new Entry[len];

            for (int j = 0; j < len; j++) {
                Entry e = parentTable[j];
                if (e != null) {
                    @SuppressWarnings("unchecked")
                    ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
                    if (key != null) {
                        Object value = key.childValue(e.value);
                        Entry c = new Entry(key, value);
                        int h = key.threadLocalHashCode & (len - 1);
                        while (table[h] != null)
                            h = nextIndex(h, len);
                        table[h] = c;
                        size++;
                    }
                }
            }
        }
	//可以重写此方法对父线程的value进项操作
	T childValue(T parentValue) {
        throw new UnsupportedOperationException();
    }

threadLocal.get()源码解析

	


    public T get() {
        //获取当前线程
        Thread t = Thread.currentThread();
        //获取线程里的Map
        ThreadLocalMap map = getMap(t);
        //如果Map不为空
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            //根据threadLocal获取的值不为空
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        //设置初始值
        return setInitialValue();
    }

	//根据线程获取Map
	ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
	//InheritableThreadLocal是一个可继承的ThreadLocal重写了getMap方法
	ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

	private T setInitialValue() {
        //获取初始值
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }
	//可以重写该方法 设置初始值
    protected T initialValue() {
        return null;
    }
	//创建一个Map
	void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

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);
    }
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值