【问题标题】:How-to provide a ThreadLocal to CompletableFutures?如何为 CompletableFutures 提供 ThreadLocal?
【发布时间】:2014-09-18 20:15:33
【问题描述】:

我需要为最终运行特定CompletableFuture.supplyAsync 供应商的所有线程提供ThreadLocal

从 javadoc 我看到CompletableFuture 使用“ForkJoinPool commonPool()”,这非常适合我的性能用例。

如何将ThreadLocal(然后删除)转移到运行特定 CompletableFuture 供应商的所有池线程?

备注:

我看到所有CompletableFuture async 完成方法都接受一个执行器。我很想使用 默认ForkJoinPool commonPool() 但如果这不可能,我想我必须覆盖ThreadPoolExecutor 并实现beforeExecute

【问题讨论】:

  • 为什么需要将它作为 ThreadLocal?您不能将值存储在您的CompletableFuture 中吗?如果我们知道您如何将任务排队,我们可能会建议一个包装器,无论如何都要小心。
  • 好问题。这是因为我在 CompletableFuture 任务中使用了一个框架(如 Hibernate),它在 Thread Locals 中使用配置数据。我很难接触到依赖于 Thread locals 的类
  • 您可以使用与Supplier相同的方法

标签: java java-8 java.util.concurrent


【解决方案1】:

我猜你必须找到自己的方式来解决它,因为ForkJoinTask 上的exec() 受到保护。对于具体的实现,您当然可以编写自己的包装器。

这就是我会为单个ThreadLocalCallable 做的事情:

public static class WithThreadLocal<V, T> implements Callable<V> {
    private final ThreadLocal<T> threadLocal;
    private final T              value;
    private final Callable<V>    callable;


    public WithThreadLocal(ThreadLocal<T> threadLocal, T value, Callable<V> callable) {
        this.threadLocal = threadLocal;
        this.value = value;
        this.callable = callable;
    }

    @Override
    public V call() throws Exception {
        T oldValue = threadLocal.get();
        try {
            threadLocal.set(value);
            return callable.call();
        } finally {
            threadLocal.set(oldValue);
        }
    }
}

从那里您可以使用ForkJoinTask.adapt()。否则你可能会对https://stackoverflow.com/a/7260332/1266906感兴趣

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 2011-05-08
    • 2016-03-20
    • 1970-01-01
    相关资源
    最近更新 更多