1位工作6年的小伙伴去某里P6一面,被问到这样一道面试题,说,为什么启动一个线程不直接调用run()方法,而要调用start()方法来启动,如果调用两次start()会有什么后果?

另外,6/7/8月份资料文档已整理,包含如下↓(还在持续更新中!):

①100道最新大厂经典面试题解析资料文档!

②15万 字Java面试题解析和配套答案!

③从应届生到高级开发都适用的简历模板!

④从入门到精通的架构师学习路线图!

⑤还有各种技术流程图,路径图!

想获取的小伙伴可以S信我【666】免费领取!

启动线程调用什么方法(为什么启动线程不直接调用run)(1)

1、run()和start()的区别

首先回答为什么启动线程不能直接调用run()方法,而要调用start()方法,我从以下4个方面来回答:

启动线程调用什么方法(为什么启动线程不直接调用run)(2)

第1:start()方法是Java线程约定的内置方法,能够确保代码在新的线程上下文中运行。

第2:start()方法包含了触创建新线程的特殊代码逻辑。run()方法是我们自己写的代码,很显然没有这个能力。

第3:如果直接调用run()方法,那么它只是一个普通的方法调用,程序中依然只有一个主线程,并且只能顺序执行,需要等待run()方法执行结束后才能继续执行后面的代码。

第4:我们创建线程的目的是为了更充分地利用CPU资源,如果直接调用run()方法,就失去了创建线程的意义了。

2、调用两次start()的后果

了解了run()方法和start()方法的区别,那如果调用两次start()方法会有什么后果呢?在Java中,线程的start()方法只能被调用一次,如果第二次调用会抛出 IllegalThreadStateException,这是一种运行时异常,多次调用 start 被认为是编程错误。

启动线程调用什么方法(为什么启动线程不直接调用run)(3)

在Java中,线程的运行状态被定义成了5个枚举值,分别是:

1、新建(NEW),线程已经创建好了,但是还没有调用start()方法启动。

2、就绪(RUNNABLE),这个状态下的线程可能正在运行,也可能还在就绪队列里面,等待系统分配CPU资源。

在操作系统中,会额外区分一种状态叫做RUNNING,但是从 Java API 的角度,并不能表示出来。关于这个问题,我在前面的视频中,有讲过关于《线程状态流转原理》有兴趣的小伙伴可以去我的主页找到。

3、阻塞(BLOCKED),表示线程处于等待Monitor Lock的状态。

4、等待(WAITING),表示线程处于条件等待状态,当触发条件后会唤醒。比如wait/notify等。

5、计时等待(TIMED_WAIT),它和WAITING状态是一样的,只是多了一个超时条件触发机制。

6、终止(TERMINATED),表示线程执行结束。

在Java API 中,影响线程运行状态的因素,如图所示:

启动线程调用什么方法(为什么启动线程不直接调用run)(4)

在我们第一次调用 start() 方法的时候,线程可能处于终止或者其他非 NEW的状态,再次调用start()方法的时候,相当于让这个正在运行的线程重新运行一遍。不管是从线程安全的角度来看,还是从线程本身的执行逻辑来看,它都是不合理的。

因此,为了避免这个问题出现,Java会先去判断当前线程的运行状态。

好了,以上就是我对Java线程的start()方法和run()方法的理解。

我是被编程耽误的文艺Tom,如果我的分享对你有帮助,请动动手指分享给更多的人。关注我,面试不再难!

,