Java 如果一个方法属于扩展线程的另一个类,但从主线程调用,它将由主线程还是子线程执行?(爪哇)

Java 如果一个方法属于扩展线程的另一个类,但从主线程调用,它将由主线程还是子线程执行?(爪哇),java,multithreading,Java,Multithreading,我知道有一些类似的问题,但我找不到一个具体的答案来回答这个问题——如果我错了,请道歉,确实有。test.toString()方法是由主线程执行,还是由调用它之前启动的测试线程执行?我们中的一些人正在为复习考试而争论这个问题,我很好奇答案是什么 public class Main { public static void main(String[] args) { test = new ThreadTest("Test", 3); test.start();

我知道有一些类似的问题,但我找不到一个具体的答案来回答这个问题——如果我错了,请道歉,确实有。test.toString()方法是由主线程执行,还是由调用它之前启动的测试线程执行?我们中的一些人正在为复习考试而争论这个问题,我很好奇答案是什么

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()相同的线程中调用。另外,不要对线程进行子类化。你最好还是做些跑步鞋。谢谢!这就是我想要检查的:)