gpt4 book ai didi

Why is there difference between static Thread.currentThread().getName() and getName()?(为什么静态Thread.currentThread().getName()和getName()有区别?)

转载 作者:bug小助手 更新时间:2023-10-28 22:13:13 27 4
gpt4 key购买 nike



I thought about a Thread object like some abstraction that carries name and static Thread.currentThread() like the way to access to that Thread object. Obviously, it's wrong assumption.

我认为Thread对象就像是带有名称和静态Thread.CurrentThread()的抽象对象,就像访问Thread对象的方式一样。显然,这是错误的假设。


public class App {

static class TestedThread extends Thread {
public void run() {
// System.out.println(Thread.currentThread().getName()); // is ok
System.out.println(this.getName());// Why is there difference?
}
}

public static void main(String[] args) {
TestedThread base = new TestedThread();
// base.start();

Thread derived = new Thread(base);
derived.setName("derived");
derived.start();
}
}

Is it something like that?
enter image description here

是这样的吗?


更多回答

Thread derived = new Thread(base); Just don't do that.

线程派生=新线程(基础);只是不要这样做。

@tkausl, ok! But I got this problem from an educational example.

@tkausl,ok!但是我从一个教育的例子中得到了这个问题。

优秀答案推荐

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是的,没错。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com