天下之事,必先处之难,而后易之。

阿里TTL异步执行上下文对象传递

Github地址:https://github.com/alibaba/transmittable-thread-local


验证对象异步传递示例:

package com.alibaba.ttl.threadpool.agent.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.alibaba.ttl.TransmittableThreadLocal;

public final class AgentDemo {

    static TransmittableThreadLocal<String> stringTransmittableThreadLocal = new TransmittableThreadLocal<String>();

    static TransmittableThreadLocal<Person> personReferenceTransmittableThreadLocal = new TransmittableThreadLocal<Person>() {
        @Override
        protected Person initialValue() {
            return new Person("unnamed", -1);
        }
    };

    static TransmittableThreadLocal<Person> personCopyTransmittableThreadLocal = new TransmittableThreadLocal<Person>() {
        @Override
        protected Person copy(Person parentValue) {
            // copy value to child thread
            return new Person(parentValue.getName(), parentValue.getAge());
        }

        @Override
        protected Person initialValue() {
            return new Person("unnamed", -1);
        }
    };
    
    private AgentDemo() {
    	throw new InstantiationError( "Must not instantiate this class" );
    }

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        expandThreadPool(executorService);

        stringTransmittableThreadLocal.set("foo - main");
        personReferenceTransmittableThreadLocal.set(new Person("jerry - reference", 1));
        personCopyTransmittableThreadLocal.set(new Person("Tom - value", 2));

        printTtlInstancesInfo("Main - Before execution of thread pool");

        Future<?> submit = executorService.submit(new Runnable() {
            @Override
            public void run() {
                printTtlInstancesInfo("Thread Pool - enter");
                stringTransmittableThreadLocal.set("foo - modified in thread pool");
                personReferenceTransmittableThreadLocal.get().setName("jerry - reference - modified in thread pool");
                personCopyTransmittableThreadLocal.get().setName("Tom - value - modified in thread pool");
                printTtlInstancesInfo("Thread Pool - leave");
            }
        });
        submit.get();

        printTtlInstancesInfo("Main - After execution of thread pool");

        executorService.shutdown();
        if (!executorService.awaitTermination(3, TimeUnit.SECONDS)) {
            System.exit(1);
        }
    }

    public static void expandThreadPool(ExecutorService executor) throws Exception {
        List<Future<?>> ret = new ArrayList<Future<?>>();
        for (int i = 0; i < 3; ++i) {
            Future<?> submit = executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            ret.add(submit);
        }
        for (Future<?> future : ret) {
            future.get();
        }
    }

    static void printTtlInstancesInfo(String msg) {
        System.out.println("====================================================");
        System.out.println(msg);
        System.out.println("====================================================");
        System.out.println("stringTransmittableThreadLocal: " + stringTransmittableThreadLocal.get());
        System.out.println("personReferenceTransmittableThreadLocal: " + personReferenceTransmittableThreadLocal.get());
        System.out.println("personCopyTransmittableThreadLocal: " + personCopyTransmittableThreadLocal.get());
    }

    public static class Person {
        String name;
        int age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
}

测试结果:

====================================================
Main - Before execution of thread pool
====================================================
stringTransmittableThreadLocal: foo - main
personReferenceTransmittableThreadLocal: Person{name='jerry - reference', age=1}
personCopyTransmittableThreadLocal: Person{name='Tom - value', age=2}
====================================================
Thread Pool - enter
====================================================
stringTransmittableThreadLocal: null
personReferenceTransmittableThreadLocal: Person{name='unnamed', age=-1}
personCopyTransmittableThreadLocal: Person{name='unnamed', age=-1}
====================================================
Thread Pool - leave
====================================================
stringTransmittableThreadLocal: foo - modified in thread pool
personReferenceTransmittableThreadLocal: Person{name='jerry - reference - modified in thread pool', age=-1}
personCopyTransmittableThreadLocal: Person{name='Tom - value - modified in thread pool', age=-1}
====================================================
Main - After execution of thread pool
====================================================
stringTransmittableThreadLocal: foo - main
personReferenceTransmittableThreadLocal: Person{name='jerry - reference', age=1}
personCopyTransmittableThreadLocal: Person{name='Tom - value', age=2}

分析:

-Before 初始化线程输出

-enter  线程重新设置传递对象的值,但并未提交,所以对象是一个默认的实例输出

-leave submit提交对象修改,对象值被修改传递赋值

-after 输出最终结果


posted @ 2024-10-12 00:35  boonya  阅读(31)  评论(0)    收藏  举报  来源
我有佳人隔窗而居,今有伊人明月之畔。
轻歌柔情冰壶之浣,涓涓清流梦入云端。
美人如娇温雅悠婉,目遇赏阅适而自欣。
百草层叠疏而有致,此情此思怀彼佳人。
念所思之唯心叩之,踽踽彳亍寤寐思之。
行云如风逝而复归,佳人一去莫知可回?
深闺冷瘦独自徘徊,处处明灯影还如只。
推窗见月疑是归人,阑珊灯火托手思忖。
庐居闲客而好品茗,斟茶徐徐漫漫生烟。

我有佳人在水之畔,瓮载渔舟浣纱归还。
明月相照月色还低,浅近芦苇深深如钿。
庐山秋月如美人衣,画堂春阁香气靡靡。
秋意幽笃残粉摇曳,轻轻如诉画中蝴蝶。
泾水潺潺取尔浇园,暮色黄昏如沐佳人。
青丝撩弄长裙翩翩,彩蝶飞舞执子手腕。
香带丝缕缓缓在肩,柔美体肤寸寸爱怜。
如水之殇美玉成欢,我有佳人清新如兰。
伊人在水我在一边,远远相望不可亵玩。