Java - propagating a threadlocal by wrapping a runnable My aim is to use a thread pool together with a thread local. I cannot use InheritableThreadLocal because the thread data is different per user and there a couple of parallel users at any time. 

So I need to push the thread local down from the mother thread to the children. 

I use guava so I want to get listenable futures back. Below is my implementation. Please look at the execute function where the logic happens. 

My question is what could go wrong here?

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import myorg.MyService;
import myorg.ThreadData;

import com.google.common.util.concurrent.AbstractListeningExecutorService;

public class ListeningDecorator extends AbstractListeningExecutorService {
    private final ExecutorService delegate;

    ListeningDecorator(final ExecutorService delegate) {
        this.delegate = checkNotNull(delegate);
    }

    @Override
    public final boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
        return this.delegate.awaitTermination(timeout, unit);
    }

    @Override
    public final boolean isShutdown() {
        return this.delegate.isShutdown();
    }

    @Override
    public final boolean isTerminated() {
        return this.delegate.isTerminated();
    }

    @Override
    public final void shutdown() {
        this.delegate.shutdown();
    }

    @Override
    public final List&lt;Runnable&gt; shutdownNow() {
        return this.delegate.shutdownNow();
    }

    @Override
    public final void execute(final Runnable command) {
        final ThreadData threadData = MyService.getThreadData();
        if (threadData == null) {
            throw new RuntimeException("threadData is null");
        }
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                MyService.setThreadData(threadData);
                command.run();

            }
        };

        this.delegate.execute(runnable);
    }
}
It might be good to revert the ThreadLocal changes in the worker thread as soon as command.run() finished (using try-finally). This would have the following advantages:

If your ExecutorService delegate (provided to the constructor) is also used somwhere else for different tasks, then currently these tasks would be affected by the changes you make to the ThreadLocals as part of ListeningDecorator.execute. For example:
ExecutorService delegateExecutor = Executors.newFixedThreadPool(10);
ListeningDecorator listeningExecutor = new ListeningDecorator(delegateExecutor);

// Sets MyService thread data
Future&lt;?&gt; future = listeningExecutor.submit(() -&gt; {
    ...
});
future.get();

// In different thread: Directly use delegateExecutor
delegateExecutor.execute(() -&gt; {
    // Would still have MyService thread data even though this was submitted
    // by different thread
    ...
});

If the MyService thread data changes were reverted as soon as command.run() finished, then this would not be an issue.
Reverting the changes might allow the garbage collector to collect MyService thread data earlier. Otherwise it might linger around indefinitely if ExecutorService delegate reuses threads.