Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How-to provide a ThreadLocal to CompletableFutures?

I need to provide a ThreadLocal to all the threads which end up running specific CompletableFuture.supplyAsync Suppliers.

From the javadoc I see that CompletableFuture uses "ForkJoinPool commonPool()" which very much fits my performance use case.

How do I transfer a ThreadLocal (and afterwards delete) to all pool threads running a specific CompletableFuture Supplier?

Remark:

I see that all CompletableFuture async completion methods accept an Executor. I would love to use the default ForkJoinPool commonPool() but if this is not possible I guess I have to override ThreadPoolExecutor and implement beforeExecute?

like image 922
jack Avatar asked Jul 27 '14 14:07

jack


1 Answers

I guess you'll have to find your own way arround it as exec() on ForkJoinTask is protected. For concrete implementations you can of course write your own wrapper.

This is what I would do for a single ThreadLocal and a Callable:

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);
        }
    }
}

From there you can use ForkJoinTask.adapt(). Otherwise you might be interrested in https://stackoverflow.com/a/7260332/1266906

like image 161
TheConstructor Avatar answered Sep 30 '22 11:09

TheConstructor