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
说点什么
您将是第一位评论人!