Thread.currentThread().getName()
and this.getName()
return different names when you start the derived
thread because this
is not the same as Thread.currentThread()
.
当您启动派生线程时,Thread.CurrentThread().getName()和this.getName()返回不同的名称,因为这与Thread.CurrentThread()不同。
You create derived
by using the constructor that takes in a Runnable
. This creates a new thread that runs the Runnable
(calls the run
method). The argument you passed, base
, is a Thread
object, which also happens to be Runnable
.
通过使用接受Runnable的构造函数创建派生。这将创建一个运行Runnable的新线程(调用Run方法)。您传递的参数base是一个Thread对象,它碰巧也是可运行的。
However, the fact that base
is a Thread
(and not some other Runnable
things) is not relevant. derived.start()
still only starts the derived
thread by calling base.run()
. It does not start the base
thread.
然而,base是一个线程(而不是其他一些可运行的东西)这一事实并不重要。Started.start()仍然只通过调用base.run()来启动派生线程。它不会启动基线程。
So Thread.currentThread()
is the derived
thread, but this
refers to the base
thread.
因此Thread.CurrentThread()是派生线程,但这指的是基线程。
It is a source of confusion that Thread implements Runnable. A Thread object is a Java Object that, once it starts, has a connection to an os thread. Having Runnable as an interface means we can separate a logical task, the Runnable, from the thing that runs it, the Thread. But letting Thread implement Runnable means the type system doesn't complain if you pass in a Thread as a constructor argument to another Thread.
这是Thread实现Runnable的一个令人困惑的来源。线程对象是一个Java对象,一旦启动,它就会连接到OS线程。将Runnable作为接口意味着我们可以将逻辑任务Runnable与运行它的Thread分离。但是让Thread实现Runnable意味着,如果您将一个Thread作为构造函数参数传递给另一个Thread,类型系统就不会出现问题。
When you pass in some thread A as a constructor argument to another thread B you are saying, A is some object with a run method that I want B to execute. When your code in A calls getName, that is getName on A, but the thread executing the code is B.
当您将某个线程A作为构造函数参数传递给另一个线程B时,您就是在说,A是具有我希望B执行的run方法的某个对象。当A中的代码调用getName时,这是A上的getName,但执行代码的线程是B。
Passing A into B doesn't mean B will use A's os thread, it only means B will execute A's run method. Thread.currentThread()
gets the Thread object that wraps the os thread executing the code.
将A传递给B并不意味着B将使用A的os线程,它只是意味着B将执行A的run方法。CurrentThread()获取包装执行代码的操作系统线程的Thread对象。
When base
is running - by calling base.start();
- getName() inside run() will correctly return the name of base, which will be something like "Thread-0" by default.
当base正在运行时-通过调用base.start();-getName()inside run()将正确地返回base的名称,默认情况下类似于“Thread-0”。
When derived is running - by calling derived.start();
- it also executes base's run() method. Here, getName() will return the name of base (not derived) because getName() refers to the TestedThread object (base) on which it was called. This is true even though derived is the thread that is currently running the run() method.
当派生函数正在运行时--通过调用派生的.start();--它还执行base的run()方法。这里,getName()将返回base(不是派生的)的名称,因为getName()引用了调用它的TestedThread对象(Base)。这是正确的,即使派生的是当前正在运行run()方法的线程。
It may be easier to understand if you add more logging to your example:
如果您在示例中添加更多日志记录,可能会更容易理解:
static class TestedThread extends Thread {
public void run() {
// Here this (running base or derived) always refers to the same instance - the base instance.
// The reason is that you created derived with base as a parameter,
// and the run from base always refers to base variable instance.
// Thread.currentThread() on the other hand refers to the instance of Thread instance on which you called start.
System.out.println("1: thid:" + Thread.currentThread().getId() + ", th ref:" + Thread.currentThread().hashCode() + ", this=" + this.hashCode() + ", " + Thread.currentThread().getName());
System.out.println("2: thid:" + Thread.currentThread().getId() + ", th ref:" + Thread.currentThread().hashCode() + ", this=" + this.hashCode() + ", " + getName());
}
}
public static void main(String[] args) {
TestedThread base = new TestedThread();
// Here base.getName() returns "Thread-0"
Thread derived = new Thread(base);
// Here derived.getName() returns "Thread-1"
// derived will execute code from base.run() - but code inside run() will refer to the base instance
derived.setName("derived");
// Here derived name is changed to "derived"
base.start();
derived.start();
}
On my computer it prints:
在我的电脑上,它打印:
1: thid:15, th ref:1801046120, this=1990684586, derived
1: thid:14, th ref:1990684586, this=1990684586, Thread-0
2: thid:15, th ref:1801046120, this=1990684586, Thread-0
2: thid:14, th ref:1990684586, this=1990684586, Thread-0
as you see, the this
always returns the same value, this is why getName() (which is actually this.getName()) returns the same value.
如您所见,This总是返回相同的值,这就是为什么getName()(实际上是this.getName())返回相同的值。
更多回答
Could you please take a relook? Did I correctly understand?
你能再看一眼吗?我的理解正确吗?
@Squared Not sure what all those arrows and colors mean, but yeah, you seem to have created a similar structure with your own classes, so I think you understood correctly. You can post another question if you are still confused.
@Squared不确定所有这些箭头和颜色是什么意思,但是的,您似乎已经用您自己的类创建了类似的结构,所以我认为您理解正确。如果你仍然不明白,你可以再发一个问题。
Sorry for confusing! I mean the problem is that when we call derived.start() we then call run() which calls base.getName() , but not the derived.getName().
对不起,让你困惑了!我的意思是,问题是,当我们调用派生的.start()时,我们会调用run(),而run()调用的是base.getName(),而不是派生的.getName()。
@Squared Yes that's right.
@Squared是的,没错。
我是一名优秀的程序员,十分优秀!