多线程核心知识总结
二.开启多线程启动世界
1.启动线程的正确和错误方式
start()和run()比较:
-
start()方法原理解读:
start方法含义:
1.启动新线程:线程对象初始化之后,调用了start方法,当前线程通常是主线程,主线程会告诉虚拟机,如果有空闲的话,启动新线程。(是否能启动,什么时候启动,是线程调度器决定)
2.准备工作:让自己处于就绪状态,就绪状态指的是,已经获取除了CPU以外的其他资源,比如说,已经设置了上下文,栈,线程状态,PC(寄存器),在准备工作完成后,线程才会进一步被操作系统或者JVM调度到执行状态,等待获取CPU资源,然后才能进行到运行状态,执行run()方法里的代码。
3.不能重复执行start():一旦开始执行,线程就从new状态进行到后续的那些状态,一旦线程执行完毕,线程就会进行到终止状态,而终止状态永远都不会返回回去。
start()源码解析:
1.启动新线程检查线程状态:
2.加入线程组:
3.调用native start0()方法(源码c/c++实现) -
run方法原理解读
Thread类中run方法的源码
@Override
public void run() {
if (target != null) {
target.run();
}
}
如果直接执行Runnable中的run方法的话,就和普通方法毫无区别,所以要想真正启动线程,不能直接调用run方法,而是应该调用start方法间接调用run方法。
启动线程常见面试题
·1.一个线程调用两次start()方法会出现什么情况?为什么?
会抛出线程状态异常。
一旦开始执行,线程会进行检查,线程就从new状态进行到后续的那些状态,一旦线程执行完毕,线程就会进行到终止状态,而终止状态永远都不会返回回去。(结合线程状态回答)
2.既然start方法已经调用了run方法,为什么不直接调用run方法呢?
只有使用了start方法,才能使线程走完完整的周期,直接调用run方法,只是一个普通方法,并不需要子线程调用。