This is Weihubeats. If you think the article is good, you can pay attention to the small playing technology of the public account. The article will be first published. No marketing numbers, no clickbait

Threads, parent threads, thread pools

We know that passing values between threads can be handled using the JDK’s built-in ThreadLocal, We can use the InheritableThreadLocal provided by the JDK if we encounter scenarios that require parent-child thread values to be passed, but many business scenarios actually need to pass the ThreadLocal values from the task submission to the thread pool to the task execution

Detailed introduction about InheritableThreadLocal refer to post before weihubeats.blog.csdn.net/article/det…

InheritableThreadLocal simple test

This is a bit confusing, so let’s take a quick look at a demo that uses an InheritableThreadLocal + thread pool

public class InheritableThreadLocalTest {
    
    private static final AtomicInteger ID_SEQ = new AtomicInteger();
    private static final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(1, r -> new Thread(r, "thread-" + ID_SEQ.getAndIncrement()));
    private static Integer i = 0;
    private static final ThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>();

    public static void main(String[] args) throws Exception {
        // Simulate an interface call
        IntStream.range(0.10).forEach(InheritableThreadLocalTest::testInheritableThreadLocal);
        THREAD_POOL.shutdown();
    }

    public static void testInheritableThreadLocal(int s) {
        inheritableThreadLocal.set("Playing technique"+ i++); Future<? > submit = THREAD_POOL.submit(new ZouTask("Task" + s));
        try {
            submit.get();
        } catch(Exception e) { e.printStackTrace(); }}public static class ZouTask implements Runnable{

        String taskName;

        public ZouTask(String taskName) {
            this.taskName = taskName;
        }

        @Override
        public void run(a) {
            System.out.println(taskName + "Thread:" + Thread.currentThread().getName() + "Obtained value:"+ inheritableThreadLocal.get()); inheritableThreadLocal.remove(); }}Copy the code

Running results:

You can see that after we get the first value, we never get the second valueInheritableThreadLocalThe value of the. The correct result should look like this:Why did this happen? The reason is very simple,InheritableThreadLocalValues are passed only when the child thread is created. The thread pool, on the other hand, will be reused after the thread is created, so it will not get the value later

TransmittableThreadLocal introduction

If there is any thread pool where there is TransmittableThreadLocal (if there is any thread pool where there is no context TransmittableThreadLocal), there is no context TransmittableThreadLocal (if there is any thread pool where there is no context TransmittableThreadLocal)

Making the address

Features (official website):

TransmittableThreadLocal(TTL) : provides the function of transmitting ThreadLocal values when the execution components of pooled and multiplexed threads such as thread pools are used to solve the problem of context transmission during asynchronous execution. A Java standard library this should provide the standard for the frame/middleware infrastructure development ability, the library function focus & 0, 17/16 support Java / 15/14/13/12/11/10/9/8/7/6.

The InheritableThreadLocal class in the JDK completes value passing from parent thread to child thread. But in the case of execution components that are pooled and reused by threads, such as thread pools, threads are created by thread pools and are pooled and reused; Parent-child ThreadLocal passes are meaningless. What the application really needs is to pass the ThreadLocal value from the time the task is submitted to the thread pool to the time the task is executed The core of the whole TransmittableThreadLocal library functions (user API and frame/middleware integration API, thread pool ExecutorService Wrapper/ForkJoinPool TimerTask and thread factory), Only ~1000 SLOC lines of code, very small

TransmittableThreadLocal use

Introduction of depend on

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
    <version>2.12.4</version>
</dependency>
Copy the code

Let’s go back to the example above

public class TransmittableThreadLocalTest {


    private static final AtomicInteger ID_SEQ = new AtomicInteger();
    private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(1, r -> new Thread(r, "thread-" + ID_SEQ.getAndIncrement()));
    private static final TransmittableThreadLocal<String> ttl = new TransmittableThreadLocal<>();
    private static Integer i = 0;



    public static void main(String[] args) throws Exception {
        // Simulate an interface call
        IntStream.range(0.10).forEach(TransmittableThreadLocalTest::testInheritableThreadLocal);
        EXECUTOR.shutdown();
    }


    public static void testInheritableThreadLocal(int s) {
        ttl.set("Playing technique"+ i++); Future<? > submit = EXECUTOR.submit(TtlRunnable.get(new ZouTask("Task" + s)));
        try {
            submit.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch(ExecutionException e) { e.printStackTrace(); }}public static class ZouTask implements Runnable{

        String taskName;

        public ZouTask(String taskName) {
            this.taskName = taskName;
        }

        @Override
        public void run(a) {
            System.out.println(taskName + "Thread:" + Thread.currentThread().getName() + "Obtained value:"+ ttl.get()); ttl.remove(); }}}Copy the code

There are a few details:

  1. withTransmittableThreadLocalreplaceInheritableThreadLocal
  2. withTtlRunnableEnhance the ORIGINAL JDKRunnableinterface

The usage of TransmittableThreadLocal is generally as follows. Some advanced uses may be such as non-intrusive Agent access

TransmittableThreadLocal is used in open source projects

TransmittableThreadLocalIt has been used in many open source projects

You can go and see for yourself

conclusion

The use of TransmittableThreadLocal ends here. Source code and principles related to the part of the interest can be studied, the official website also has some instructions, here will not explain for the time being