TTL篇-TtlAgent的使用

发布时间:2024年01月15日

接上篇,TTL篇-TTL的使用-CSDN博客

TtlAgent是什么

ttl使用的典型代码是如下所示,

@Data
    @AllArgsConstructor
    public static class Bean {
        private String name;
    }

    @Test
    public void testBean() throws InterruptedException {
        TransmittableThreadLocal<Bean> transmittableThreadLocal = new TransmittableThreadLocal<>();
        transmittableThreadLocal.set(new Bean("a"));
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        TtlExecutors.getTtlExecutor(executorService).execute(() -> {
            System.out.println("初始拷贝:" + transmittableThreadLocal.get());
            Bean bean = transmittableThreadLocal.get();
            bean.setName("a1");
        });


        Thread.sleep(1000);
        TtlExecutors.getTtlExecutor(executorService).execute(() -> System.out.println("初始拷贝:" + transmittableThreadLocal.get()));

    }

为了使用TransmittableThreadLocal,需要配合TtlExecutors和TtlRunnable。所以在生成上使用的话多有不变,能不能有一个方法对于默认的java线程池进行增强,使得对于普通java线程池,提交的任务,默认使用的TtlRunnable;

官方提供了解决方案,TtlAgent。

TtlAgent的使用效果

如下代码,因为,使用默认的线程池,提交的任务,就会变成TTlRunanle任务,所以打印正常打印出a;

public class TtlAgentTest {
    public static void main(String[] args) {
        TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();
        transmittableThreadLocal.set("a");

        ThreadPoolExecutor threadPoolExecutor = new
                ThreadPoolExecutor(1, 10, 1000, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(100));

        AtomicInteger a = new AtomicInteger();
        threadPoolExecutor.execute(() -> {
            System.out.println(transmittableThreadLocal.get());
        });
    }
}

怎么使用TtlAgent

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
    <version>2.2.0</version>
</dependency>

需要指定java启动参数,

-javaagent:D:\maven_jar\com\alibaba\transmittable-thread-local\2.2.0\transmittable-thread-local-2.2.0.jar -Xbootclasspath/a:D:\maven_jar\com\alibaba\transmittable-thread-local\2.2.0\transmittable-thread-local-2.2.0.jar

然后就可以正常跑TtlAgentTest 用例了。

参数详解:

-javaagent:这个是指定javaAgent代理的jar包

-Xbootclasspath:因为修饰了JDK标准库的类ThreadPoolExecutor,标准库由bootstrap class loader加载;修饰后的JDK类引用了TTL的代码,所以Java Agent使用方式下TTL Jar文件需要配置到boot class path上。

实现原理:

可以通过debug看到,增强的代码实现,$1 = com.alibaba.ttl.TtlRunnable.get($1, false, true);

结论

  1. 通过使用TtlAgent,可以增强ThreadPoolExecutor线程池,默认提交的任务,会被
    TtlRunnable get(),转换TTtlRunnable任务;
  2. 对于javaAgent需要增强jdk类库的代码,需要使用-Xbootclasspath,让agent的代码bootstrapClassLoader加载,否则默认的类加载器是systemClassLoader/appClassLoader。
文章来源:https://blog.csdn.net/qq_27886773/article/details/135605198
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。