Search code examples
javamultithreadingjava-8thread-localinheritable-thread-local

"withInitial" vs "InitialValue" In threadLocal


I am bit confused between initialValue vs withInital method for threadLocal.

Consider a situation, I have data in parent thread, and I am using InheritableThreadLocal.

public class Parent extends Thread {
public static ThreadLocal<String> data = new InheritableThreadLocal<String>() {
    @Override
    protected String initialValue() {
        return "temp";
    }
};

public static void main(String[] args) {
    new Parent().start();
}

public void run() {
    data.set("parent data");
    System.out.println("Parent Thread Value :" + data.get());
    new ChildThread().start();
}

class ChildThread extends Thread {
    public void run() {
        System.out.println("Child Thread Value :" + Parent.data.get());
    }
}
}

Output:

Parent Thread Value : parent data
Child Thread Value : parent data

I am creating thread in parent, and calling child thread. The child is inheriting data from parent thread.

Now if I initialize variable data (In line 2) like this:

public static ThreadLocal<String> data =InheritableThreadLocal.withInitial(() -> "temp");

I get the following output:

Parent Thread Value :parent data
Child Thread Value :temp

I am not sure why its happening. I read oracle's document, but didn't get something useful. https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html#withInitial-java.util.function.Supplier- https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html#initialValue--

I wonder how can I achieve the same output with withInitial instead of using initialValue?


Solution

  • withInitial does not create an InheritableThreadLocal. It only creates a regular ThreadLocal, which is why you see temp in the output.

    withInitial is a static method, so it can't be overridden by InheritableThreadLocal to do something different instead, like returning an InheritableThreadLocal.

    So you can't do the same thing, but with withInitial, because it doesn't return the type of object you need.