为什么启动一个线程不用run()方法,而是用start()方法

在使用java多线程时,有三种方式创建线程 当使用继承Thread来实现多线程时, 我们会把线程执行的代码写在run() 方法中, 使用Thread的start()方法来启动一个线程。 代码如下:

public class ThreadDemo extends Thread{
          
   
    @Override
    public void run() {
          
   
        System.out.println("this is demo thread :"+Thread.currentThread().getName());
    }

    public static void main(String[] args) {
          
   
        ThreadDemo t = new ThreadDemo();
        t.start();
        System.out.println("this is main thread :"+Thread.currentThread().getName());
    }
}

执行结果:

this is main thread :main
this is demo thread :Thread-0

Process finished with exit code 0

在main方法中,为什么不直接 调用 t.run() 来启动线程? 因为t.run()是调用实例方法(会直接在当前线程中执行run中的逻辑), 而start才是启动线程,在新线程中执行run方法里的逻辑。

我们来看看Thread类的 start 方法究竟做了什么?

public synchronized void start() {
          
   
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        group.add(this);

        boolean started = false;
        try {
          
   
            start0();
            started = true;
        } finally {
          
   
            try {
          
   
                if (!started) {
          
   
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
          
   
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

可以看到,start() 方法中调用了 start0(),而 start0() 是一个native方法。 native 关键字表示该方法是一个本地方法,java中提供了机制可以调用C的方法,它可以通过动态库加载,可以通过navtive来调用。

Java中的线程,其实是由操作系统来提供的。 在Java高级语言与操作系统之间,是通过JVM来调用的。

start0()是JVM层面实现的方法。 start0() 方法会调用操作系统底层的指令去创建一个线程,并且启动线程。 操作系统通过调度算法,把生成的线程调度,分配给不同的CPU。 操作系统会调用JVM的run,最终调回Java Thread的run方法。 最终使得run中的逻辑在线程中运行。

当线程执行结束后,JVM会完成销毁。

经验分享 程序员 微信小程序 职场和发展