[英]If a method belongs to another class that extends Thread but is called from the main thread, will it be executed by main or a child thread? (Java)
I know there are some similar questions out there, but I couldn't find one specifically answering this question - apologies if I was wrong, and there is. 我知道那里也有一些类似的问题,但是我找不到一个专门回答这个问题的方法-如果我错了,我深表歉意。 Would the test.toString() method be executed by the main thread, or the test thread that I started prior to it being called? test.toString()方法是由主线程执行还是由我在调用它之前启动的测试线程执行? A group of us are arguing about this for test revision and I am curious to what the answer is. 我们中的一群人为此争论进行测试修订,我很好奇答案是什么。
public class Main {
public static void main(String[] args) {
test = new ThreadTest("Test", 3);
test.start();
System.out.println(test.toString());
}
}
public class ThreadTest extends Thread {
public ThreadTest(String n, int x) {
setName(n);
}
@Override
public String toString() {
return(getName() + ": x = " + x);
}
public void run() {
//Nothing of any relevance to the problem occurs here
}
}
Calls are always executed on the calling thread. 调用始终在调用线程上执行。 Masses of code are based on this - for example the whole security and transaction infrastructure of the spring framework. 基于此的大量代码-例如spring框架的整个安全和事务基础结构。
This fact can be proved rather easy: 这个事实可以证明很容易:
public class Main {
static ThreadLocal<String> threadContext = new ThreadLocal<String>();
public static void main(String[] args) throws InterruptedException {
threadContext.set("Main");
TestThread test = new TestThread();
new Thread(test).start();
System.out.println("Main: " + test.getContext());
}
static class TestThread implements Runnable {
@Override
public void run() {
threadContext.set("ThreadTest");
System.out.println("TestThread: " + getContext());
}
String getContext() {
return threadContext.get();
}
}
}
And as @DavidEhrmann already said: You should implement Runnable
instead of extending Thread
. 就像@DavidEhrmann所说的:您应该实现Runnable
而不是扩展Thread
。
The toString()
call is executed on the main thread. toString()
调用在主线程上执行。 The main thread is invoking Main.main()
; 主线程正在调用Main.main()
; main()
directly invokes test.toString()
. main()
直接调用test.toString()
。
Just because your output prints the string "Test" doesn't mean that's the thread that is executing it. 仅仅因为您的输出显示字符串“ Test”并不意味着那是执行它的线程。 Thread
has state; Thread
有状态; setName(...)
sets that state (and your class TestThread
is a subclass of Test
so it inherits this as well). setName(...)
设置状态(您的TestThread
类是Test
的子类,因此它也继承了此状态)。 In your toString()
implementation you're just printing that state... not the actual name of the executing thread. 在您的toString()
实现中,您只是在打印该状态……而不是执行线程的实际名称。
To prove this, change your TestThread.toString()
method to also print the name of the currently executing thread and re-run: 为了证明这一点,请更改您的TestThread.toString()
方法,以同时显示当前正在执行的线程的名称并重新运行:
@Override
public String toString() {
return(getName() + ": x = " + x + " executed on thread " + Thread.currentThread().getName());
}
You will see the following print to standard out: 您将看到以下打印输出为标准输出:
Test: x = 3 executed on thread main
Full code: 完整代码:
public class Main {
public static void main(String[] args) {
ThreadTest test = new ThreadTest("Test", 3);
test.start();
System.out.println(test.toString());
}
}
public class ThreadTest extends Thread {
private int x;
public ThreadTest(String n, int x) {
setName(n);
this.x = x;
}
@Override
public String toString() {
return(getName() + ": x = " + x + " executed on thread " + Thread.currentThread().getName());
}
public void run() {
//Nothing of any relevance to the problem occurs here
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.