start和run方法启动线程对比
public class StartAndRunMethod {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println(Thread.currentThread().getName());
};
runnable.run();
new Thread(runnable).start();
}
}
输出
main
Thread-0
run方法是由主线程去执行的
start启动了子线程
start方法原理
start是请求启动新线程
主线程启动以后会去请求JVM,我有一个子线程要执行任务,JVM会在空闲的情况下去执行。运行线程本质就是去请求JVM来运行线程。
调用start的顺序并不能决定线程的执行顺序,可能线程一线执行start,线程二再执行的start,但是可能存在线程二先执行,线程的执行是由调度器去实现的。
start会让两个线程去执行,一个是主线程,或者是其他的线程来执行start方法,第二个就是我们创建的线程。
准备工作 :线程执行之前也是需要做准备工作,它会去获取除了CPU以外的资源,如:上下文,栈等。当准备完毕之后才可以被JVM调度到执行状态,才能获取到CPU的资源。
不能两次调用start方法
如果对调用两次start方法会抛出异常
Exception in thread "main" java.lang.IllegalThreadStateException
start的运行流程
- start启动线程的时候会检查线程状态
- 检查完毕之后会加入线程组
- 加入线程组之后会调用start0()
从start的源码来看,他有一个threadStatus=0的初始值,表示线程还没有被启动,如果启动了会改变这个值,以至于执行到下面的这段代码,抛出了异常
if (threadStatus != 0)
throw new IllegalThreadStateException();
start0()方法是C++写的,这个就不作深入学习
run方法执行
主要的还是以下的三行代码
if (target != null) {
target.run();
}
就是一个普通方法运行