当两个(!)实际生成一个新线程时,在新线程上调用run()和start()之间的区别究竟是什么?

nbu*_*urk 2 java concurrency multithreading runnable

所以,这个问题在此之前(这里和这里)得到了回答,答案对我来说完全有意义:

run()只调用对象的run()方法Thread,但不产生新的线程.因此,run()方法中的代码实际上是在调用它的同一个线程上执行的. start()另一方面,将线程实例移交给调度程序并调用run()它,因此它生成一个新线程,在该线程上run()执行方法的代码.

但是,我正在努力真正理解这是什么意思,所以我开发了一个案例来验证语句:

public class Test extends Thread{

    public void run() {
        System.out.println("run() called on thread: " + getName());
    }

    public static void main(String[] args) throws Exception {
        System.out.println("main() called on thread: " + Thread.currentThread().getName());
        Test t = new Test();
        t.start(); // OR t.run();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,如果上面的描述是真的,那么程序的输出应该是如果我t.run()用来执行print语句,那么线程的名称应该是相同的,因为不应该创建新的线程并且t它只是在与它相同的线程上运行是创建于.另一方面,t.start()实际上应该给我两个不同的线程名称.

但是,在这两种情况下我都得到输出:

main() called on thread: main
run() called on thread: Thread-0
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么调用t.run()也会生成一个新线程并且实际上不输出:

main() called on thread: main
run() called on thread: main
Run Code Online (Sandbox Code Playgroud)

Flo*_*etz 6

你在Thread对象上调用getName(),你期望什么?当然,您将获得该Thread对象的名称.只有那不是您当前正在操作的线程,例如:

Test t = new Test();
t.getName(); // What do you think you'll get?
Run Code Online (Sandbox Code Playgroud)

我认为你想知道的将会得到答案 Thread.currentThread().name();

让我重新说一下:你没有问"给我这个方法运行的当前线程的名称"但是"给我调用这个方法的线程对象的名称." - 这是不一样的.


Nat*_*hes 5

在Test对象上调用getThread会返回分配给该线程对象的名称,而不管执行Test对象的run方法的线程是什么.

如果您修复代码,以便始终获取当前线程的名称:

public class Test extends Thread{

    public void run() {
        System.out.println("run() called on thread: " + Thread.currentThread().getName());
    }

    public static void main(String[] args) throws Exception {
        System.out.println("main() called on thread: " + Thread.currentThread().getName());
        Test t = new Test();
        t.start(); // OR t.run();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你会得到显示start使用不同线程的结果:

main() called on thread: main
run() called on thread: Thread-5
Run Code Online (Sandbox Code Playgroud)

并运行使用相同的线程:

main() called on thread: main
run() called on thread: main
Run Code Online (Sandbox Code Playgroud)