小知识(8) TTL使用

TTL

在使用线程池等会池化复用线程的执行组件情况下,提供ThreadLocal值的传递功能,解决异步执行时上下文传递的问题。

一、ThreadLocal 的问题

1、内存泄漏:

如果一个 ThreadLocal 变量引用的对象没有被正确地清理,那么即使线程结束了,这些对象仍然会被持有,从而导致内存泄漏。
解决:在不再需要时调用 ThreadLocal 的 remove() 方法来显式释放资源。

2、线程池中的问题:

当使用线程池时,由于线程会被复用,因此如果不适当地管理 ThreadLocal,可能会导致数据污染或者内存泄漏。
解决:在线程执行完任务之后清理 ThreadLocal。

二、TransmittableThreadLocal (TTL)

为了解决线程池中 ThreadLocal 的问题,阿里巴巴开源了一个扩展 ThreadLocal 的库叫做 TransmittableThreadLocal (TTL),它可以在使用线程池的情况下正确地处理 ThreadLocal 的传递和清理。

TTL 的特点

  • 自动传递:在创建新线程时,自动将当前线程的 ThreadLocal 变量传递给新线程。
  • 自动清理:在任务执行完毕后,自动清理 ThreadLocal 变量,防止内存泄漏。

三、TTL 使用示例

<!-- ttl -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
    <version>2.14.4</version>
</dependency>

ThreadLocal 问题:线程池上下文丢失

ThreadLocal<Integer> TL = new ThreadLocal<>();
TL.set(1);
ExecutorService executorService = ThreadUtil.newExecutor(3);
executorService.execute(() -> {
    log.info("TL:{}", TL.get()); // null
});
ThreadUtil.sleep(1, TimeUnit.SECONDS);

TTL 解决:

@Slf4j
public class TtlTest {
    public static void main(String[] args) {
        ThreadLocal<String> TTL = new TransmittableThreadLocal<>();
        TTL.set("hello");
        ExecutorService executor = Executors.newFixedThreadPool(2);
        executor.submit(() -> {
            TTL.set("hello-111");
            log.info("executor value: {}", TTL.get()); // "executor" 线程复用时,如果ThreadLocal中的值未remove,之后的相同线程会拿到这个线程设置的值
        });

        log.info("value: {}", TTL.get());

        TtlExecutors.getTtlExecutorService(executor).submit(() -> {
            TTL.set("hello-222");
            log.info("ttl value: {}", TTL.get());  // "ttl" 线程复用时,如果ThreadLocal中的值未remove,ttl方式会自动remove,不会保留
        });

        for (int i = 0; i < 5; i++) {
            int finalI = i;
            executor.submit(() -> {
                log.info("executor index:{} value: {}", finalI, TTL.get()); // executor
            });
            TtlExecutors.getTtlExecutorService(executor).submit(() -> {
                log.info("ttl index:{} value: {}", finalI, TTL.get()); // ttl
            });
        }

        log.info("value: {}", TTL.get());
        executor.shutdown();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑清

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值