InheritableThreadLocal and thread pools

后端 未结 2 1865
无人共我
无人共我 2020-12-16 18:43

I have a problem which I don\'t really think has a solution but I\'ll try here anyway. My application uses a thread pool and some of the threads in this pool have an inherit

相关标签:
2条回答
  • 2020-12-16 18:58

    The constructor of a runnable runs in the thread of the caller, whereas the run method runs in the child thread. You can use this fact to transfer information from the parent to the child thread. See:

    public class ThreadlocalApplication {
    static public ThreadLocal<String> tenantId = new ThreadLocal<>();
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        System.out.println(Thread.currentThread().getName());
        ThreadlocalApplication.tenantId.set("4711");
        executor.submit(new AsyncTask()).get();
        executor.shutdown();
    }
    
    static class AsyncTask implements Runnable {
        private String _tenantId;
    
        public AsyncTask() {
            System.out.println(Thread.currentThread().getName());
            _tenantId = ThreadlocalApplication.tenantId.get();
        }
    
        @Override
        public void run() {
            ThreadlocalApplication.tenantId.set(_tenantId);
            System.out.println(Thread.currentThread().getName());
            System.out.println(ThreadlocalApplication.tenantId.get());
        }
    }
    }
    

    And this is the result

    main
    main
    pool-1-thread-1
    4711
    
    0 讨论(0)
  • 2020-12-16 19:04

    It sounds like this is a poor use-case for the "inheritable" flavour of thread-locals.

    My advice would be to just use a regular TheadLocal and do the initialization explicitly; e.g. passing the initial value from the parent thread to the child thread as a parameter or something.

    (I was going suggest that you force initialization of the thread-local the child thread by having it fetch the value as soon as it starts. But that risks a race-condition; e.g. if the parent thread is returned to the pool before the child thread starts executing.)


    I guess what I am asking is if there is a way to access the value of the parent thread's thread local variable from a child thread.

    There isn't a way to do this.

    And, judging from your other comments, I doubt that you mean "parent" and "child" in the normal sense ... where the parent thread creates the child thread.

    But here's an idea. Instead of trying to share a variable between threads, share a fixed value (e.g. a request ID), and use that as a key for a shared Map. Use the Map entries as the shared variables.

    0 讨论(0)
提交回复
热议问题