ThreadLocal evolution --InheritableThreadLocal

There are introduced before ThreadLocal, JDK and later made an upgrade for this version InheritableThreadLocal, today to take the next.

Why should I upgrade

First, we have to think about it, why upgrade? It is necessary to talk about the function of the ThreadLocal.

We know, ThreadLocal is designed for the multi-threaded environment, for each thread to have its own copy, so you can solve the problem of multi-threaded modified to some extent. However, we can do an expand on this basis, for example context, we can use the ThreadLocal for each thread has its own context, usually written ThreadLocal<Context>, all such modifications on this thread can be made to take advantage of everyone.

Imagine this point, if we create a child thread, then this sub-thread can get to the parent thread of contextit? Theoretically we hope to achieve this effect, in reality? let us see:

public class ThreadLocalContext {

    private static ThreadLocal<Context> context = new ThreadLocal<>();

    static class Context {

        String name;

        int value;
    }

    public static void main(String[] args) {
        Context context = new Context();
        context.name = "mainName";
        context.value = 10;
        ThreadLocalContext.context.set(context);

        Thread childThread = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        Context childContext = ThreadLocalContext.context.get();
                        System.out.println(childContext.name);
                        System.out.println(childContext.value);
                    }
                }
        );
        childThread.start();
    }
}

After running the main method directly in the child thread throwing error, so really in line with our expectations, but if we want to achieve 子线程可以获取到父线程的 contextthis effect is going to help them?

First thought is generated when the child thread, the parent thread ThreadLocal in the value passed to the child thread. While doing so to achieve the effect, but the process is complicated, and the code is highly invasive.

This time can be used InheritableThreadLocalup.

What is InheritableThreadLocal

See source

Let us look at its source, we should not be afraid, it's rarely the source:

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);
    }
}

First, it inherited from ThreadLocal, it is actually an expanded version of ThreadLocal, the next step is these three methods, in fact, these three methods in ThreadLocal are there, we take a look:

    T childValue(T parentValue) {
        throw new UnsupportedOperationException();
    }

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

    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

In addition to childValuethe method in ThreadLocal is thrown, the other two methods are nearly identical in the two classes, but for different objects only, but threadLocalsand inheritableThreadLocalsall ThreadLocal.ThreadLocalMaptypes, that have said in the previous article, is a key to 弱引用the Entry, this fall is not the point.

Let us look at inheritableThreadLocals is initialized and when, can be learned from the source:

    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
                // 省略无关代码
                ...
                Thread parent = currentThread();
                ...
                // 省略无关代码
                ...
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
                ...
        }

When we generate a sub-thread calls the constructor Thread through parent thread, its construction methods will eventually call the init method. As can be seen from here, inheritableThreadLocals from inheritableThreadLocals parent thread, and that this also explains why the inheritableThreadLocals supports variable parent thread stored in the sub-thread.

how to use

Let us return to the example or context mentioned above, transformation with InheritableThreadLocal:

public class ThreadLocalContext {

    private static InheritableThreadLocal<Context> context = new InheritableThreadLocal<>();

    static class Context {

        String name;

        int value;
    }

    public static void main(String[] args) {
        Context context = new Context();
        context.name = "mainName";
        context.value = 10;
        ThreadLocalContext.context.set(context);

        Thread childThread = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        Context childContext = ThreadLocalContext.context.get();
                        System.out.println(childContext.name);
                        System.out.println(childContext.value);
                    }
                }
        );
        childThread.start();
    }
}

After the run, not only did not throw an exception, and the output of the parent thread set good values ​​in the child thread. Happy!

to sum up

Today shared InheritableThreadLocal, mainly because of the sharing session Wednesday in Ctrip heard others talk about sharing in this regard, Speaker told a more common problem, if we submit the job, then use the thread pool, thread pool thread in when the mission, how to get thread context of submitted jobs, then we should use open source components Ali TTL, I will be introduced later.

Ctrip also has added a month, though there are a lot of big companies feel the drawbacks, such as communication and difficulties, but there are a lot of advantages, such as technology sharing sessions, although it has also sneak in to participate, but have more technology and related opportunities to learn and exchange, also quite good.

Are interested can visit my blog or follow me number of public, headline number, maybe there will be surprises.

https://death00.github.io/

Public number: Jian Cheng Road

Guess you like

Origin www.cnblogs.com/death00/p/12037594.html