阿里开源的TransmittableThreadLocal的正确使用姿势

这篇具有很好参考价值的文章主要介绍了阿里开源的TransmittableThreadLocal的正确使用姿势。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 目录

1. 直接使用 TransmittableThreadLocal

2. 在使用线程池的情况下使用 TransmittableThreadLocal

3. 使用 TtlExecutors 的使用案例 (推荐)

4. 拓展


                TransmittableThreadLocal是阿里巴巴开源的一个线程本地变量,它是ThreadLocal的一个增强版,可以在线程池等多线程环境下使用,解决了ThreadLocal在多线程环境下的一些问题。

在多线程环境下,ThreadLocal可以避免线程安全问题,但是在使用线程池等多线程环境时,ThreadLocal可能会出现一些问题。例如,当使用线程池时,线程池中的线程可能会被多个任务共享,如果使用ThreadLocal存储数据,可能会导致数据被错误地共享。

        TransmittableThreadLocal解决了这个问题,它可以在多线程环境下正确地传递数据。具体来说,当一个线程从线程池中获取到一个线程时,TransmittableThreadLocal会自动将当前线程的ThreadLocal副本传递给新的线程,从而保证数据的正确性。

        下面有几个简单的示例,演示了如何使用TransmittableThreadLocal

1. 直接使用 TransmittableThreadLocal

public class TransmittableThreadLocalDemo {
    private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();

    public static void main(String[] args) {
        // 在主线程中设置TransmittableThreadLocal的值
        threadLocal.set("Hello, World!");

        // 在新线程中获取TransmittableThreadLocal的值
        Thread thread = new Thread(() -> {
            String value = threadLocal.get();
            System.out.println("TransmittableThreadLocal value in new thread: " + value);
        });
        thread.start();
    }
}

        在这个示例中,我们首先在主线程中将一个字符串存储到TransmittableThreadLocal中。然后,我们创建一个新线程,在新线程中获取TransmittableThreadLocal的值并打印出来。由于TransmittableThreadLocal可以正确地传递数据,因此新线程中获取到的值与主线程中设置的值是相同的。

        需要注意的是,TransmittableThreadLocal是ThreadLocal的一个增强版,因此在使用时需要注意一些细节。例如,TransmittableThreadLocal的使用方式与ThreadLocal略有不同,需要使用TtlRunnable和TtlCallable等类来包装Runnable和Callable。此外,TransmittableThreadLocal也需要进行垃圾回收,否则可能会导致内存泄漏

2. 在使用线程池的情况下使用 TransmittableThreadLocal

        在使用线程池的情况下,如果需要使用TransmittableThreadLocal,可以使用阿里巴巴的TTL库来实现。TTL库提供了一些工具类,可以方便地在使用线程池的情况下使用TransmittableThreadLocal。

        具体来说, 可以使用TtlRunnable和TtlCallable等类来包装 Runnable 和 Callable,从而在执行任务时自动传递ThreadLocal的值。例如,下面是一个使用线程池和TransmittableThreadLocal的示例:

public class ThreadPoolDemo {
    private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 在主线程中设置TransmittableThreadLocal的值
        threadLocal.set("Hello, World!");

        // 在线程池中执行任务
        executorService.execute(TtlRunnable.get(() -> {
            String value = threadLocal.get();
            System.out.println("TransmittableThreadLocal value in new thread: " + value);
        }));

        // 等待任务执行完成
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.SECONDS);
    }
}

        在这个示例中,我们首先创建了一个线程池,然后在主线程中设置了一个TransmittableThreadLocal的值。接着,我们使用TtlRunnable包装了一个Runnable任务,并将其提交到线程池中执行。在执行任务时,TtlRunnable会自动传递ThreadLocal的值,从而保证了数据的正确性

3. 使用 TtlExecutors 的使用案例 (推荐)

        TtlExecutors是阿里巴巴开源的一个工具类,用于在使用线程池的情况下使用TransmittableThreadLocal。具体来说,TtlExecutors提供了一些工具方法,可以方便地将线程池和TransmittableThreadLocal结合起来使用。

下面是一个使用TtlExecutors的示例代码:        

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;

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

public class TtlExecutorsDemo {
    private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>();

    public static void main(String[] args) {
        // 创建一个固定大小的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 在主线程中设置TransmittableThreadLocal的值
        threadLocal.set("Hello, World!");

        // 使用TtlExecutors包装线程池
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(executorService);

        // 提交任务到线程池中
        ttlExecutorService.submit(() -> {
            String value = threadLocal.get();
            System.out.println("Task is running in thread: " + Thread.currentThread().getName() + ", TransmittableThreadLocal value: " + value);
        });

        // 关闭线程池
        ttlExecutorService.shutdown();
    }
}

        
        在这个示例中,我们首先创建了一个固定大小的线程池,并在主线程中设置了一个TransmittableThreadLocal的值。接着,我们使用TtlExecutors.getTtlExecutorService()方法将线程池包装成一个支持TransmittableThreadLocal的线程池。最后,我们使用包装后的线程池提交了一个任务,并在任务中获取了TransmittableThreadLocal的值

4. 拓展

        除了在使用线程池的情况下使用TransmittableThreadLocal外,还有一些其他的使用案例。

例如,在使用Dubbo等分布式框架时,TransmittableThreadLocal可以用于在服务调用链路中传递数据。具体来说,可以在服务提供者和消费者中使用TransmittableThreadLocal来传递一些上下文信息,例如请求ID、用户信息等。这样可以方便地在服务调用链路中获取这些信息,从而实现一些功能,例如日志追踪、权限校验等。

另外,TransmittableThreadLocal还可以用于一些需要在多个线程之间共享数据的场景。例如,在使用Netty等网络编程框架时,可以使用TransmittableThreadLocal来在不同的事件处理器之间共享一些上下文信息,例如连接信息、请求信息等。

总之,TransmittableThreadLocal可以用于在多线程环境下传递数据,解决了ThreadLocal在多线程环境下的一些问题。在使用TransmittableThreadLocal时需要注意一些细节,例如需要进行垃圾回收等。同时,也需要根据具体的使用场景来选择合适的使用方式。文章来源地址https://www.toymoban.com/news/detail-560669.html

到了这里,关于阿里开源的TransmittableThreadLocal的正确使用姿势的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 开源模型应用落地-qwen1.5-7b-chat与sglang实现推理加速的正确姿势(一)

         SGLang is a structured generation language designed for large language models (LLMs). It makes your interaction with LLMs faster and more controllable by co-designing the frontend language and the runtime system。简单来说就是,SGLang简化了LLM程序的编写并提高了执行效率,SGLang可以将常见的LLM任务加速高达5倍。    

    2024年04月12日
    浏览(43)
  • Kali字典正确使用姿势

    终端输入wordlists,可以查看自带字典。ls -al 查看具体路径 /usr/share/wordlists/目录下带了rockyou的字典。2009年一家名叫rockyou的公司遭到了黑客攻击,他们的密码列表以明文存储,黑客下载了所有的密码列表并且公开。rockyou.txt包含14341564个唯一密码,用于32603388个帐户。 rockyou.t

    2024年02月06日
    浏览(46)
  • 自定义redission装配和集成分布式开源限流业务组件ratelimiter-spring-boot-starter的正确姿势

    自定义redission装配和集成分布式开源限流业务组件ratelimiter-spring-boot-starter的正确姿势   由于使用了redisson-spring-boot-starter,在自定义redisson装配的时候会被redisson-spring-boot-starter里面的start默认装配了,同时在使用开源分布式限流组件ratelimiter-spring-boot-starter的时候,这个里面

    2024年02月07日
    浏览(55)
  • Android中正确使用Handler的姿势

    在Android中,Handler是一种用于在不同线程之间传递消息和任务的机制。以下是在Android中正确使用Handler的一些姿势: 1. 在主线程中创建Handler对象 在Android中,只有主线程(也称为UI线程)可以更新UI。因此,如果您需要在后台线程中执行某些任务并更新UI,则需要使用Handler将任

    2024年02月11日
    浏览(47)
  • windows自带远程桌面连接的正确使用姿势

    目前远程办公场景日趋广泛,对远程控制的需求也更加多样化,windows系统自带了远程桌面控制,在局域网内可以实现流程的远程桌面访问及控制。互联网使用远程桌面则通常需要使用arp等内网穿透软件,市场上teamviewer、Todesk、向日葵等远程桌面软件十分优秀,window系统也自

    2024年02月10日
    浏览(46)
  • SpringBoot项目中使用缓存Cache的正确姿势!!!

    缓存可以通过将经常访问的数据存储在内存中,减少底层数据源如数据库的压力,从而有效提高系统的性能和稳定性。我想大家的项目中或多或少都有使用过,我们项目也不例外,但是最近在review公司的代码的时候写的很蠢且low, 大致写法如下: 其实Spring Boot 提供了强大的缓

    2023年04月10日
    浏览(31)
  • elasticsearch 父子文档使用must not 正确姿势

    1、基于elasticsearch 父子文档进行子条件查询父文档 2、需要查询出子文档不存在的父文档 1、父文档clue_list 关联很多的子文档,我们用roam子文档做测试! 2、roam子文档的结构 需求是查询出roam子文档不存在的数据,由于我们es的所有数据companyId == 1 我们可以用must not来排除 co

    2024年02月05日
    浏览(44)
  • 逍遥自在学C语言 | 条件控制的正确使用姿势

    在C语言中,有三种条件判断结构:if语句、if-else语句和switch语句。 第一位闪亮登场,有请今后会一直教我们C语言的老师 —— 自在。 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。 基本语法 代码示例 运行结果 基本语法 代码示例 运行结果 代码示例 在这个示例中

    2024年02月03日
    浏览(54)
  • 【趟坑记录】d3.zoom()的正确使用姿势 @d3.v7

    在开发一个D3应用的时候遇到了一个 zoom 相关的问题,记录解决思路与方案 问题重现 最近在开发一个D3应用的时候遇到了一个 zoom 相关的问题,应用里有一个功能叫 全景聚焦 。我们都知道画布由两个标签组成(见实现autoZoom(),画布自适应放缩并居中@D3.js-v5),最外层的是固定

    2024年02月16日
    浏览(43)
  • 开闭原则正确姿势, 使用AOP优雅的记录日志, 非常的哇塞

    👳我亲爱的各位大佬们好😘😘😘 ♨️ 本篇文章记录的为 JDK8 新特性 Stream API 进阶 相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。 ♨️ 如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛 👨‍🔧 个人主页 : 阿千弟 🔥

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包