Java 当我从线程继承时,类中的每个方法都在新线程上运行吗?

Java 当我从线程继承时,类中的每个方法都在新线程上运行吗?,java,multithreading,inheritance,extends,java-threads,Java,Multithreading,Inheritance,Extends,Java Threads,我有一个程序,每次创建一个新线程的实例时,我都希望在新线程上运行一个特定的类。为此,我使用了多线程的extend-Thread继承方法。然而,我想知道的是:当我为某个类扩展Thread时,我调用的该类的每个方法(比如在构造函数中或以后)是在线程上运行,还是只在run()方法中调用的方法在新线程上运行 示例: public class Entity extends Thread { Entity() { super("Bob"); start();

我有一个程序,每次创建一个新线程的实例时,我都希望在新线程上运行一个特定的类。为此,我使用了多线程的
extend-Thread
继承方法。然而,我想知道的是:当我为某个类
扩展Thread
时,我调用的该类的每个方法(比如在构造函数中或以后)是在线程上运行,还是只在run()方法中调用的方法在新线程上运行

示例:

public class Entity extends Thread {
    Entity() {
       super("Bob"); 
       start();
       method2(); //will this run on the new Thread alongside the one called in run()?

    }

    public void run() {
       method1(); //will only this method run on the new Thread? 
    }

    int method1() {
         return 1;
    }

    int method2() {
         return 2;
    }

}
public class World {
    public static void main(String args[]) {
        Entity example = new Entity(); 
        example.method2(); //will this run on the new Thread?

    }

}
或:

public class Entity extends Thread {
    Entity() {
       super("Bob"); 
       start();
       method2(); //will this run on the new Thread alongside the one called in run()?

    }

    public void run() {
       method1(); //will only this method run on the new Thread? 
    }

    int method1() {
         return 1;
    }

    int method2() {
         return 2;
    }

}
public class World {
    public static void main(String args[]) {
        Entity example = new Entity(); 
        example.method2(); //will this run on the new Thread?

    }

}

答案很简单,您想要在另一个线程中运行的所有线程都必须在方法中调用。

只有从实体的run方法发出的method1调用在通过调用run-in实体的构造函数创建的新线程中被调用。从main方法对实体的method2调用由主线程执行。同样,start由main方法调用,因此实体构造函数对method2的调用由主线程执行

在实体构造函数中,调用超类的start方法,从而创建一个新线程(在新线程中将调用实体对象的run方法),然后当前线程继续调用method2。不仅method2不会在新线程中被调用,而且,根据启动新线程所需的时间,实体上的run方法很可能会在调用method2后执行(尽管没有指定哪个先发生,但两个线程都可以先执行)

您可以通过记录线程名称来测试哪个线程正在运行某些东西。使用
this.getName()
返回线程对象的名称,而不是执行代码的线程的名称。您可以将实体的method1和method2代码更改为

int method1() {
     System.out.println("in method1 of " + this.getName() 
     + ", executed from " + Thread.currentThread().getName());
     return 1;
}

int method2() {
     System.out.println("in method2 of " + this.getName() 
     + ", executed from " + Thread.currentThread().getName());
     return 2;
}
为了看到两者之间的差异,这导致

in method2 of Bob, executed from main
in method1 of Bob, executed from Bob
in method2 of Bob, executed from main
请注意,引入println可能会改变程序线程的执行顺序

构造函数用于初始化对象;让线程在构造函数完成之前启动容易出错,因为线程在对象完全初始化之前执行run方法


让您的实体扩展线程是很尴尬的,因为有几个原因,您不能从任何其他子类中创建子类,并且您可能会意外地重写线程上的方法。通常,使用可以使用线程池的执行器比让对象尝试管理自己的专用线程要好。如果您特别想要在自己的线程上运行并异步通信的对象,您可以查看,特别是。

只有通过调用
start()
方法才能创建新线程。调用
run()

因此,使用
Thread
类的正确方法是仅调用构造函数和类外的
start()
方法。类应该执行的所有操作都应该适合
run()
方法


假设您有以下代码

public class MyClass extends Thread {
    public void myMethod() {
       //implementation
    }
    public void run() {
       myMethod();
       //other implementation
    }
}
public class Application {
    public static void main(String args[]) {
       new MyClass().start();
    }
}
此代码创建一个新的
MyClass
实例,并调用其
start()
方法,该方法创建一个新线程并自动在其上运行
run()
方法


相反,考虑这个代码:

public class Application {
    public static void main(String args[]) {
       new MyClass().run();
    }
}

这些代码只在当前线程上执行该方法


因此,为了回答您的问题,第一个
method2()
调用将不会在单独的线程上运行<如果通过
start()
方法调用
run()
,则code>method1()
调用将仅在新线程上运行。第二个
method2()
调用将不会在单独的线程上运行



另外,正如在另一个答案中提到的,在构造函数中调用
start()
从来都不是一个好的做法。

您在尝试时看到了什么?我不能确切地说,我将尝试编写一个输出更明显的程序。因为当我添加打印语句时,所有的数字都会立即打印出来。我将尝试使用Thread.sleep(),1-不,您应该更喜欢使用
可运行的
,并将其包装为
线程的一个实例,2-不,或者更确切地说,除非这些方法是在
线程
运行
方法的上下文中执行的,因为您没有创建一种新的
线程
(这就是扩展的含义)。您只需要在其中运行一些代码。
run
方法位于
Thread
中并不意味着它在新线程上运行:它在调用它的线程上运行。e、 g.如果您调用
thread.start()
,它将位于新线程上,但如果您直接调用
thread.run()
,则它不会位于新线程上。