我写了一个小程序,我将线程名称存储在类级字段中并打印它。
public class ThreadClass implements Runnable {
private String threadName = null;
@Override
public void run() {
System.out.println(" thread name " + threadName);
System.out.println(" current thread >>>>>> "
+ Thread.currentThread().getName());
threadName = Thread.currentThread().getName();
}
}
我写了一个测试类,在那里我创建了10个线程并启动它们。
public class ThreadController {
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread(threadClass, "T1");
Thread t2 = new Thread(threadClass, "T2");
Thread t3 = new Thread(threadClass, "T3");
Thread t4 = new Thread(threadClass, "T4");
Thread t5 = new Thread(threadClass, "T5");
Thread t6 = new Thread(threadClass, "T6");
Thread t7 = new Thread(threadClass, "T7");
Thread t8 = new Thread(threadClass, "T8");
Thread t9 = new Thread(threadClass, "T9");
Thread t10 = new Thread(threadClass, "T10");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
t9.start();
t10.start();
}
}
我得到了以下输出。
thread name null
thread name null
thread name null
current thread >>>>>> T1
current thread >>>>>> T6
current thread >>>>>> T2
thread name T2
thread name T2
thread name null
thread name null
thread name null
current thread >>>>>> T4
current thread >>>>>> T7
current thread >>>>>> T8
current thread >>>>>> T9
thread name T1
current thread >>>>>> T5
thread name T1
current thread >>>>>> T3
current thread >>>>>> T10
我怀疑的是,如果每个线程都创建了一个字段变量的本地副本,那么为什么我并不总是将线程名称变为null。 对不起,如果这听起来像一个愚蠢的问题,但我正在努力学习线程。
答案 0 :(得分:3)
线程将不创建其访问的字段的本地副本。在您的实现中,所有线程都试图访问实例threadClass
中的相同字段,这就是为什么它始终不是null
。
如下所示更改您的来源,您将获得预期的行为。
Thread t1 = new Thread(new ThreadClass(), "T1");
Thread t2 = new Thread(new ThreadClass(), "T2");
Thread t3 = new Thread(new ThreadClass(), "T3");
Thread t4 = new Thread(new ThreadClass(), "T4");
Thread t5 = new Thread(new ThreadClass(), "T5");
Thread t6 = new Thread(new ThreadClass(), "T6");
Thread t7 = new Thread(new ThreadClass(), "T7");
Thread t8 = new Thread(new ThreadClass(), "T8");
Thread t9 = new Thread(new ThreadClass(), "T9");
Thread t10 = new Thread(new ThreadClass(), "T10");
答案 1 :(得分:1)
虽然您已命名变量threadName,但它与Thread对象的名称无关。如果使用Thread构造函数方法将String作为Thread名称传递,则可以使用Thread.currentThread()。getName()返回此String,但不会更改threadName变量。
如果您希望以编写代码的方式使用变量,那么您应该在ThreadClass中使用一个接收String的构造函数并设置threadName,如下所示:
public ThreadClass(String name){
this.threadName = name;
}
你可以像这样使用这个构造函数:
Thread t1 = new Thread(new ThreadClass("T1"));
请注意,如果您仍想使用Thread.currentThread()。getName(),则必须执行以下操作:
Thread t1 = new Thread(new ThreadClass("T1"),"T1-name for getName");
干杯
答案 2 :(得分:0)
你这样做:
System.out.println(" thread name " + threadName);
之前:
threadName = Thread.currentThread().getName();
因此,您所拥有的输出在消息中是正常的:thread name null
。每个线程一旦启动就会打印线程名称为null。
由于您对所有线程使用相同的ThreadClass
实例,因此在一个中更改类变量threadName
也将在其他线程中更改。
实际上,只有ThreadClass
的一个实例(而且是threadName
的一个实例),并且每个线程都使用对ThreadClass
的引用。
这就是为什么你看到这个语句打印所有线程名称的原因:
System.out.println(" current thread >>>>>> " + Thread.currentThread().getName());
但不是这样:
System.out.println(" thread name " + threadName);
了解Java如何处理对象和对象的引用将有助于您使用线程。