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?
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.
As mentioned in the other answer, withInitial is defined in ThreadLocal and returns an object of a type SuppliedThreadLocal that extends ThreadLocal and not InheritableThreadLocal. Since such a static factory method is not defined (yet?) in the JDK, you can create your own inheritable utility version:
static final class SuppliedInheritableThreadLocal<T> extends InheritableThreadLocal<T> {
private final Supplier<? extends T> supplier;
SuppliedInheritableThreadLocal(Supplier<? extends T> supplier) {
this.supplier = Objects.requireNonNull(supplier);
}
@Override
protected T initialValue() {
return supplier.get();
}
public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
return new SuppliedInheritableThreadLocal<>(supplier);
}
}
public static ThreadLocal<String> data = SuppliedInheritableThreadLocal.withInitial(() -> "temp");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With