admin管理员组文章数量:1123192
Somehow when I try to set value to the InheritableThreadLocal field while creating an object of class that inherites Thread I get strange behavior: my object doesn't have the value I set while invoking constructor when the execution reaches the printing line in run() method. At the same time when I try to run a thread that inherites my class it sees the value I set while doing previos creation.
I tried to run the following code:
public class InheritableThreadLocalExample {
public static void main(String[] args) {
ThreadOne threadOne = new ThreadOne("user-one", "thread-one");
threadOne.start();
ThreadTwo threadTwo = new ThreadTwo("user-two", "thread-two");
threadTwo.start();
}
public static class ThreadOne extends Thread {
protected static final InheritableThreadLocal<String> USERNAME = new InheritableThreadLocal<>();
public ThreadOne(String username, String threadName) {
super(threadName);
USERNAME.set(username);
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ". Username: " + USERNAME.get());
}
}
public static class ThreadTwo extends ThreadOne {
public ThreadTwo(String username, String threadName) {
super(username, threadName);
}
}
}
The output is:
thread-two. Username: user-one
thread-one. Username: null
Why is this happening?
Somehow when I try to set value to the InheritableThreadLocal field while creating an object of class that inherites Thread I get strange behavior: my object doesn't have the value I set while invoking constructor when the execution reaches the printing line in run() method. At the same time when I try to run a thread that inherites my class it sees the value I set while doing previos creation.
I tried to run the following code:
public class InheritableThreadLocalExample {
public static void main(String[] args) {
ThreadOne threadOne = new ThreadOne("user-one", "thread-one");
threadOne.start();
ThreadTwo threadTwo = new ThreadTwo("user-two", "thread-two");
threadTwo.start();
}
public static class ThreadOne extends Thread {
protected static final InheritableThreadLocal<String> USERNAME = new InheritableThreadLocal<>();
public ThreadOne(String username, String threadName) {
super(threadName);
USERNAME.set(username);
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ". Username: " + USERNAME.get());
}
}
public static class ThreadTwo extends ThreadOne {
public ThreadTwo(String username, String threadName) {
super(username, threadName);
}
}
}
The output is:
thread-two. Username: user-one
thread-one. Username: null
Why is this happening?
Share Improve this question asked 7 hours ago bepopovbepopov 254 bronze badges 1 |1 Answer
Reset to default 3The constructor of ThreadOne
is executed by the main thread, therefore, the statement USERNAME.set(username);
inside this constructor sets the value for the main thread. But the actual values of the inheritable thread locals of the main thread were copied in the constructor of Thread
, i.e. the preceding super(threadName);
, already.
Therefore, the first thread inherits the state before the first USERNAME.set(username);
call whereas the second thread inherits the state after that call; the inheritance relationship is irrelevant, as we can demonstrate:
public class InheritableThreadLocalExample {
public static void main(String[] args) {
ThreadOne threadOne = new ThreadOne("user-one", "thread-one");
printValue();
threadOne.start();
Thread threadTwo = new Thread(
InheritableThreadLocalExample::printValue, "thread-two");
// things happening after Thread's constructor are irrelevant:
ThreadOne.USERNAME.set("user-two");
threadTwo.start();
}
static void printValue() {
System.out.println(Thread.currentThread().getName()
+ ". Username: " + ThreadOne.USERNAME.get());
}
public static class ThreadOne extends Thread {
protected static final InheritableThreadLocal<String> USERNAME
= new InheritableThreadLocal<>();
public ThreadOne(String username, String threadName) {
super(threadName);
USERNAME.set(username);
}
@Override
public void run() {
printValue();
}
}
}
main. Username: user-one
thread-one. Username: null
thread-two. Username: user-one
We can easily set the intended values in the main thread without subclasses:
public class InheritableThreadLocalExample {
static final InheritableThreadLocal<String> USERNAME
= new InheritableThreadLocal<>();
public static void main(String[] args) {
USERNAME.set("user-one");
Thread threadOne = new Thread(
InheritableThreadLocalExample::printValue, "thread-one");
USERNAME.set("user-two");
Thread threadTwo = new Thread(
InheritableThreadLocalExample::printValue, "thread-two");
// demonstrate that each thread has its own value
// and main doesn't need a value:
USERNAME.remove();
threadOne.start();
threadTwo.start();
}
static void printValue() {
System.out.println(Thread.currentThread().getName()
+ ". Username: " + USERNAME.get());
}
}
thread-one. Username: user-one
thread-two. Username: user-two
本文标签: javaUnable to set value to InheritableThreadLocal field in class inherited ThreadStack Overflow
版权声明:本文标题:java - Unable to set value to InheritableThreadLocal field in class inherited Thread - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736553405a1944543.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
ThreadOne
and when it does so. – Holger Commented 7 hours ago