Java启动线程为什么只能用start()而不能用run()

我们知道启动一个线程使用的是Thread类的start()方法,但start()方法最后仍然会自动调用run()方法,那为什么不直接使用run()方法呢?

错误样例

先看下面这个例子:

public class test {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()->{
            System.out.println(Thread.currentThread().getName());
        });
        thread.setName("线程2");
        thread.run();

        thread.join();
        System.out.println(Thread.currentThread().getName());
    }
}

首先创建了一个名称为“线程2”的子线程,这里我们使用run()方法去运行这个线程,正常结果应该是线程2和main线程一起输出,但是结果如下:

main
main

这就说明我们是不能使用run()方法去替代start()方法的。

原因

首先我们需要明白一个问题:JAVA真的可以开启线程吗?
答案是否定的。Java是没有权限去开启线程、操作硬件的,它通过调用底层的C++代码来开启一个新的线程。查看start()方法源码,我们会发现它调用了一个native修饰的start0()方法。

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) {

            }
        }
    }

	// 本地方法start0
    private native void start0();

这里说明了java是不能开启线程的,只能通过本地方法start0()启动线程,而当我们直接使用run()方法时,既然线程都还没有开启,又怎么会得到正常的结果呢?

当我们调用run()方法时,线程并没有开启,这就相当于我们只是单纯地通过对象去调用一个普通方法而已,此时执行的线程还是主线程,并且当前只有主线程在执行(不算上守护线程),因此得到两个main是理所当然了。

而我们使用start()方法时,线程已经开启,因此就得到了正确的结果。

public class test {
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(()->{
            System.out.println(Thread.currentThread().getName());
        });
        thread.setName("线程2");
        thread.start();

        thread.join();
        System.out.println(Thread.currentThread().getName());
    }
}

结果如下:

线程2
main

总结

当我们new了一个 Thread时,线程就进入了新建状态。调⽤ start() ⽅法,会启动⼀个线程并使线程进⼊了就绪状态,当分配到时间⽚后就可以开始运⾏了。 start() 会执⾏线程的相应准备⼯作,然后⾃动执⾏ run() ⽅法的内容,这是真正的多线程⼯作。 但是,直接执⾏ run() ⽅法,会把 run()⽅法当成⼀个 main 线程下的普通⽅法去执⾏,并不会在某个线程中执⾏它,所以这并不是多线程⼯作。

说白了就是一句话:调⽤ start() ⽅法⽅可启动线程并使线程进⼊就绪状态,直接执⾏ run() ⽅法的话不会以多线程的⽅式执⾏。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值