我们都知道Java多线程的实质是调用Thread类的run()方法,每次我们开启新线程都得调用start()方法,那我们能不能直接调用run()方法进行启动线程呢?
start()和run()的比较
1 |
|
从运行结果我们可以看出使用start()方法才能创建出新线程,使用run()方法只是在main线程里面调用一个普通的方法而已。
start()方法原理解读
我们先来看的一段代码
1 |
|
我们调用了两次start()方法,结果抛出了线程状态不符合的异常。为什么会抛出这样的异常呢,我们来看看start()方法的源码。
从start()的源码我们可以看到线程刚刚new实例但是还没有启动的时候的状态未0,当线程已经调用start()方法启动线程后,线程的状态已经不为0了,此时再调用一次start()方法就会抛出异常。
继续分析start()方法我们会发现start方法的执行流程如下:
- 检查线程状态,只有NEW状态下的线程才能继续,否则会抛出IllegalThreadStateException
- 被加入线程组
- 调用start0()方法启动线程
注意点:start0()是native类型的,它的底层是c++实现的。start方法是被synchronized修饰的方法,可以保证线程安全,由JVM创建的main方法线程和system组线程,并不会通过start来启动。
run()方法原理解读
没啥好说的了,经典三行代码。
总结
Java启动多线程的方法是通过调用Thread类的start()方法且不能调用多次,直接调用Thread类的run()方法并不能启动线程,和我们在main里面调用类的普通方法没什么区别。