Я хотел, чтобы ParentThread
установил threadId
в значение (скажем, p1
), передаваемое его конструктору. Тогда для всех его потомков threadId
установлено значение p1.c1
, p1.c2
и так далее. Я написал следующий код:
public class InheritableThreadLocalDemo {
public static void main(String[] args)
{
ParentThread pt = new ParentThread("p1");
pt.start();
}
}
class ParentThread extends Thread {
static int childCount = 0;
public static InheritableThreadLocal threadId = new InheritableThreadLocal() {
public Object childValue(Object parentValue)
{
return parentValue.toString() + ".c" + (++childCount) ; //this is line 18 where NullPointerException is occuring
}
};
public ParentThread(String pThreadId) {
threadId.set(pThreadId);
}
public void run()
{
System.out.println("Thread id:" + threadId.get());
ChildThread childThread1 = new ChildThread();
childThread1.start();
ChildThread childThread2 = new ChildThread();
childThread2.start();
}
}
class ChildThread extends Thread {
public void run()
{
System.out.println("Child Thread Value :" + ParentThread.threadId.get());
}
}
Он печатает:
Thread id:null
Exception in thread "Thread-0" java.lang.NullPointerException
at com.mahesha999.examples.java.multithreading.ParentThread$1.childValue(InheritableThreadLocalDemo.java:18)
at java.lang.ThreadLocal$ThreadLocalMap.<init>(Unknown Source)
at java.lang.ThreadLocal$ThreadLocalMap.<init>(Unknown Source)
at java.lang.ThreadLocal.createInheritedMap(Unknown Source)
at java.lang.Thread.init(Unknown Source)
at java.lang.Thread.init(Unknown Source)
at java.lang.Thread.<init>(Unknown Source)
at com.mahesha999.examples.java.multithreading.ChildThread.<init>(InheritableThreadLocalDemo.java:37)
at com.mahesha999.examples.java.multithreading.ParentThread.run(InheritableThreadLocalDemo.java:30)
Я отладил в eclipse и обнаружил, что внутри конструктора threadId
правильно установлено значение p1
, но внутри ParentThread.run()
, это читается как null
. Также внутри childValue
, .toString()
вызывается на null
, бросая NullPointerException
.
Q1. * Почему значение, установленное в конструкторе, не отображается внутри run()
и childValue()
?
Также я хочу, чтобы это ParentClass
можно было использовать повторно, то есть Я должен иметь возможность иметь такие серии, как
p2.c1
, p2.c2
и т. Д. p3.c1
, p3.c2
и т. Д. - и и так далее
Мне кажется, для этого я должен сделать childCount
и threadId
non-stati c. Но удаление static
из обеих этих переменных дает мне ошибку времени компиляции
Cannot make a static reference to the non-static field ParentThread.threadId
внутри ChildThread.run()
для ParentThread.threadId.get()
. Но теперь я не могу представить, как сделать эти InheritableThreadLocal
переменными уникальными для каждого потока в каждом экземпляре.
Q2. Как мне это сделать?
Q3. Или здесь что-то не так глупо? Является ли «уникальным для каждого потока на экземпляр» не что иное, как «уникальным только для каждого экземпляра», и нам вообще не нужна концепция локального потока в этом случае? Поэтому все ThreadLocal
переменные должны быть static
по соглашению?