InheritableThreadLocal使用

从名字上可以看出InheritableThreadLocal就是用来解决父子线程继承时使用的问题,其实大致都可以猜到,我们先来看看例子:

public class InheritableThreadLocalT {
    public static final ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        threadLocal.set("hello");
        System.out.println(threadLocal.get());

        new Thread() {
            @Override
            public void run() {
                System.out.println(threadLocal.get());
            }
        }.start();
    }
}

再来看看使用另外的

public class InheritableThreadLocalT {
    public static final InheritableThreadLocal<String> threadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args) {
        threadLocal.set("hello");
        System.out.println(threadLocal.get());

        new Thread() {
            @Override
            public void run() {
                System.out.println(threadLocal.get());
                new Thread(){
                    @Override
                    public void run() {
                        System.out.println(threadLocal.get());
                    }
                }.start();
            }
        }.start();
    }
}

想必使用方式都一目了然了,就是子线程可访问到父线程里面值,使用也是很简单的,下面我们来看看原理,首先Thread类中有两个map,以及在创建线程时会去关联父线程创建map,会把父线程中的值都拷贝过来,所以如果父线程如果重新set了,对子线程不可见,子线程set了,对父线程也不可见,因为不是同一个map

public class Thread implements Runnable {
	ThreadLocal.ThreadLocalMap threadLocals = null;
	ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
	
	private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
		init(g, target, name, stackSize, null, true);
	}
	
	private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) {
		......
		Thread parent = currentThread();
		if (inheritThreadLocals && parent.inheritableThreadLocals != null)
			this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
		......
	}
}

然后我们看下InheritableThreadLocal的实现,这三个方法都是重写父类ThreadLocal的,所以我们最终还是要看看ThreadLocal在相关方法上的实现

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
    protected T childValue(T parentValue) {
        return parentValue;
    }

    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;
    }

    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
}
经验分享 程序员 微信小程序 职场和发展