Java 如果一个方法属于扩展线程的另一个类,但从主线程调用,它将由主线程还是子线程执行?(爪哇)
我知道有一些类似的问题,但我找不到一个具体的答案来回答这个问题——如果我错了,请道歉,确实有。test.toString()方法是由主线程执行,还是由调用它之前启动的测试线程执行?我们中的一些人正在为复习考试而争论这个问题,我很好奇答案是什么Java 如果一个方法属于扩展线程的另一个类,但从主线程调用,它将由主线程还是子线程执行?(爪哇),java,multithreading,Java,Multithreading,我知道有一些类似的问题,但我找不到一个具体的答案来回答这个问题——如果我错了,请道歉,确实有。test.toString()方法是由主线程执行,还是由调用它之前启动的测试线程执行?我们中的一些人正在为复习考试而争论这个问题,我很好奇答案是什么 public class Main { public static void main(String[] args) { test = new ThreadTest("Test", 3); test.start();
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
}
}
调用总是在调用线程上执行。大量的代码都是基于此的——例如spring框架的整个安全性和事务基础设施 这一事实很容易证明:
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();
}
}
}
公共类主{
静态ThreadLocal threadContext=new ThreadLocal();
公共静态void main(字符串[]args)引发InterruptedException{
threadContext.set(“Main”);
TestThread test=新的TestThread();
新线程(test).start();
System.out.println(“Main:+test.getContext());
}
静态类TestThread实现可运行{
@凌驾
公开募捐{
threadContext.set(“ThreadTest”);
System.out.println(“TestThread:+getContext());
}
字符串getContext(){
返回threadContext.get();
}
}
}
正如@davidermann已经说过的:您应该实现Runnable
,而不是扩展Thread
,toString()
调用在主线程上执行。主线程正在调用main.main()
main()
直接调用test.toString()
仅仅因为输出输出了字符串“Test”,并不意味着这就是执行它的线程<代码>线程有状态setName(…)
设置该状态(您的类TestThread
是Test
的子类,因此它也继承了该状态)。在toString()
实现中,您只是在打印该状态。。。不是执行线程的实际名称
为了证明这一点,请将TestThread.toString()
方法更改为同时打印当前正在执行的线程的名称并重新运行:
@Override
public String toString() {
return(getName() + ": x = " + x + " executed on thread " + Thread.currentThread().getName());
}
您将看到以下打印到标准输出:
Test:x=3在主线程上执行
完整代码:
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
}
}
我没有添加run方法,因为这是我们正在讨论的代码的简化版本,它实际上没有做任何特殊的事情-在run方法中根本没有调用toString()方法。扩展线程的类的方法与扩展日期的类的方法没有什么不同。如果您使用类的对象调用,那么该方法将被调用。是否有方法可以确定具体由哪个线程调用?它是main,还是在调用它之前运行的测试线程?方法在调用它们的线程中被调用,即使它是线程上的方法。toString()将在与main()相同的线程中调用。另外,不要对线程进行子类化。你最好还是做些跑步鞋。谢谢!这就是我想要检查的:)