Welcome everyone

使用加强的ThreadLocal

java 汪明鑫 616浏览 0评论

ThreadLocal 大家都不陌生,存储线程变量,线程间是隔离的,互不影响,一般我们在保存或者传递上下文信息会使用

但是有一定的局限性,比如不支持子线程的传递,我们如果在父线程开了多线程处理逻辑,在多线程中就丢失了父线程存储的变量

 

这时我们可以使用 InheritableThreadLocal

package pers.wmx.springbootfreemarkerdemo.util;

import lombok.extern.slf4j.Slf4j;

/**
 * @author wangmingxin03
 * Created on 2021-12-07
 */
@Slf4j
public class InheritableThreadLocalMain {
    // 可以传递给子线程
    private static  final InheritableThreadLocal<Integer> THREAD_LOCAL = new InheritableThreadLocal<>();

    public static void main(String[] args) {
        int traceId = 1;
        THREAD_LOCAL.set(traceId);
        log.info("父线程 threadLocal:{}", THREAD_LOCAL.get());

        // 开启子线程 (如果用普通的ThreadLocal,子线程是读不到的,线程间隔离的)
        new Thread(() -> {
            log.info("子线程 threadLocal:{}", THREAD_LOCAL.get());
        }).start();

    }

}

 

这样就可以跨线程传递

InheritableThreadLocal 也有一定的局限性,比如我们的线程是线程池复用的,用这个数据就会乱掉

这时我们可以用阿里开源的  TransmittableThreadLocal

 

package pers.wmx.springbootfreemarkerdemo.util;

import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.TtlRunnable;

import lombok.extern.slf4j.Slf4j;

/**
 * https://github.com/alibaba/transmittable-thread-local
 *
 * @author wangmingxin03
 * Created on 2021-12-07
 */
@Slf4j
public class TransmittableThreadLocalMain {
    private static final TransmittableThreadLocal<Integer> THREAD_LOCAL = new TransmittableThreadLocal<>();

    // 线程复用也可以传递
    private static  final ExecutorService THREAD_POOL = Executors.newFixedThreadPool(5);

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10 ; i++) {
            // 模拟10次请求
            new TomcatThread(i).start();
        }

        Thread.sleep(3000);
        THREAD_POOL.shutdown();
    }

    static class TomcatThread extends Thread {
        int index;

        public TomcatThread(int index) {
            this.index = index;
        }

        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            log.info(name + ":" + index);
            THREAD_LOCAL.set(index);

            THREAD_POOL.submit(Objects.requireNonNull(TtlRunnable.get(new BusinessThread(name))));
        }
    }

    static class BusinessThread implements Runnable {
        private String parentThreadName;

        public BusinessThread(String parentThreadName) {
            this.parentThreadName = parentThreadName;
        }

        @Override
        public void run() {
            log.info("parentThreadName:" + parentThreadName + ":" + THREAD_LOCAL.get());
        }
    }
}


 

22:04:30.401 [Thread-10] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-10:9
22:04:30.401 [Thread-1] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-1:0
22:04:30.401 [Thread-4] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-4:3
22:04:30.401 [Thread-8] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-8:7
22:04:30.401 [Thread-6] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-6:5
22:04:30.401 [Thread-5] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-5:4
22:04:30.401 [Thread-7] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-7:6
22:04:30.401 [Thread-9] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-9:8
22:04:30.401 [Thread-3] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-3:2
22:04:30.401 [Thread-2] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - Thread-2:1
22:04:30.410 [pool-1-thread-1] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-1:0
22:04:30.410 [pool-1-thread-4] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-5:4
22:04:30.410 [pool-1-thread-5] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-4:3
22:04:30.410 [pool-1-thread-3] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-9:8
22:04:30.410 [pool-1-thread-2] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-8:7
22:04:30.410 [pool-1-thread-1] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-6:5
22:04:30.410 [pool-1-thread-3] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-3:2
22:04:30.410 [pool-1-thread-4] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-2:1
22:04:30.410 [pool-1-thread-5] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-10:9
22:04:30.411 [pool-1-thread-2] INFO pers.wmx.springbootfreemarkerdemo.util.TransmittableThreadLocalMain - parentThreadName:Thread-7:6

 

转载请注明:汪明鑫的个人博客 » 使用加强的ThreadLocal

喜欢 (2)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz