ThreadLocal难以在异步编程或Reactive编程中使用 - bsideup


与同步编程不同,由于大量上下文切换和线程池,异步编程使得ThreadLocal难以使用。
最简单的是……根本不使用ThreadLocals:D
例如,在Project Reactor中,您可以使用ContextAPI:

Mono.just("Hello %s")
    .delaySubscription(Flowable.timer(1, TimeUnit.SECONDS))
    .transform(flux -> Mono.deferWithContext(ctx -> {
        return flux.doOnNext(greeting -> {
           
// Get it from the Context
            String userId = ctx.get(
"userId");
            System.out.println(String.format(greeting, userId));
        });
    }))

   
// Put something to the Context, e.g. in the web filter
    .subscriberContext(Context.of(
"userId", "bsideup"))
    .block();

在Reactor内部,它不使用任何ThreadLocal,也不会暴露于多线程问题。
但是,此API是Reactor特定的,并且未在Reactive Streams规范中定义,并且您不会在RxJava之类的库中找到它

其他想法:
可以提出一个通用的Scheduler抽象,这样,探测钩子只需要设置一次。直到JDK中出现此类API。

另一种选择是始终在线程上运行所有内容(类似于Netty的想法),但这会严重影响性能。