InheritableThreadLocal源码阅读

在进行多线程编程时,咱们常常须要线程池子线程和父线程进行ThreadLocal信息传递,实现一些业务处理。编程

先看一个例子

public class App {
    static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();

    public static void main(String[] args) {
        threadLocal.set(new Integer(123));

        Thread thread = new SonThread();
        thread.start();

        System.out.println("main = " + threadLocal.get());
    }

    static class SonThread extends Thread {
        @Override
        public void run() {
            System.out.println("SonThread = " + threadLocal.get());
        }
    }
}

输出结果

main = 123
SonThread = null

使用InheritableThreadLocal

static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<Integer>();

输出结果

main = 123
SonThread = 123

经过InheritableThreadLocal咱们能够实现父子线程之间ThreadLocal信息传递。多线程

查看InheritableThreadLocal源码

重写了getMap和createMap方法。ide

public class InheritableThreadLocal<T> extends ThreadLocal<T> {

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

    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
    }
  • 属性inheritableThreadLocals为ThreadLocal属性,说明ThreadLocal为父线程和子线程实现了不一样的ThreadLocalMap存储。
  • 当咱们建立一个新的线程的时候X,X线程就会有 ThreadLocalMap 类型的 inheritableThreadLocals ,由于它是 Thread 类的一个属性。
/* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
  • 再经过一个 for 循环,不断的把当前线程的这些值复制到咱们新建立的线程X 的inheritableThreadLocals 中。就这样,就ok了。
  • 结果就是咱们建立的新线程X 的inheritableThreadLocals 变量中已经有了值了。
  • 那么我在新的线程X中调用threadlocal.get() 方法,首先会获得新线程X 的 inheritableThreadLocals,而后,再根据threadlocal.get()中的 threadlocal,就可以获得这个值。
  • 这样就避免了 新线程中获得的 threadlocals 没有东西。以前就是由于没有东西,因此才拿不到值。

因此说 整个 InheritableThreadLocal 的实现原理就是这样的。this

使用例子

public static void main(String[] args) {
        threadLocal.set(new Integer(123));

        ExecutorService fixPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(index * 500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            fixPool.execute(new Runnable() {
                public void run() {
                    System.out.println("Thread = " + Thread.currentThread().getName() + ", SonThread = " + threadLocal.get());
                }
            });
        }
        fixPool.shutdown();
    }

使用前:线程

Thread = pool-1-thread-1, SonThread = null
Thread = pool-1-thread-2, SonThread = null
Thread = pool-1-thread-3, SonThread = null
Thread = pool-1-thread-4, SonThread = null
Thread = pool-1-thread-5, SonThread = null
Thread = pool-1-thread-6, SonThread = null
Thread = pool-1-thread-7, SonThread = null
Thread = pool-1-thread-8, SonThread = null
Thread = pool-1-thread-9, SonThread = null
Thread = pool-1-thread-10, SonThread = null

使用InheritableThreadLocal以后:code

Thread = pool-1-thread-1, SonThread = 123
Thread = pool-1-thread-2, SonThread = 123
Thread = pool-1-thread-3, SonThread = 123
Thread = pool-1-thread-4, SonThread = 123
Thread = pool-1-thread-5, SonThread = 123
Thread = pool-1-thread-6, SonThread = 123
Thread = pool-1-thread-7, SonThread = 123
Thread = pool-1-thread-8, SonThread = 123
Thread = pool-1-thread-9, SonThread = 123
Thread = pool-1-thread-10, SonThread = 123
相关文章
相关标签/搜索