Java多线程start()方法原理解析
1、为什么启动线程不用run()方法而是使用start()方法
run()方法只是一个类中的普通方法,调用run方法跟调用普通方法一样
而start()是创建线程等一系列工作,然后自己调用run里面的任务内容。
验证代码:
/**
*@data2019/11/8-下午10:29
*描述:run()和start()
*/
publicclassStartAndRunMethod{
publicstaticvoidmain(String[]args){
Runnablerunnable=newRunnable(){
@Override
publicvoidrun(){
System.out.println(Thread.currentThread().getName());
}
};
runnable.run();
newThread(runnable).start();
}
}
结果:
main
Thread-0
2、start()源码解读
启动新线程检查线程状态
publicsynchronizedvoidstart(){
/**
*Thismethodisnotinvokedforthemainmethodthreador"system"
*groupthreadscreated/setupbytheVM.Anynewfunctionalityadded
*tothismethodinthefuturemayhavetoalsobeaddedtotheVM.
*
*Azerostatusvaluecorrespondstostate"NEW".
*/
if(threadStatus!=0)
thrownewIllegalThreadStateException();
关于threadStatus源码:
/* *Javathreadstatusfortools,defaultindicatesthread'notyetstarted' */ privatevolatileintthreadStatus;
通过代码可以看到就是threadStatus就是记录Thread的状态,初始线程默认为0.
加入线程组
/*Notifythegroupthatthisthreadisabouttobestarted *sothatitcanbeaddedtothegroup'slistofthreads *andthegroup'sunstartedcountcanbedecremented.*/ group.add(this);
调用start0()
booleanstarted=false;
try{
start0();
started=true;
}finally{
try{
if(!started){
group.threadStartFailed(this);
}
}catch(Throwableignore){
/*donothing.Ifstart0threwaThrowablethen
itwillbepassedupthecallstack*/
}
}
}
start0()方法使用c++编写的方法,这些代码在gdk代码中,所以这里不再这里探究了。
3、start()方法不能使用多次
通过刚刚源码分析,就知道start方法刚开始就检查线程状态,当线程创建后或结束了,该状态就不同于初始化状态就会抛出IllegalThreadStateException异常。
测试代码:
start不可以使用多次
/**
*@data2019/11/8-下午11:57
*描述:start不可以使用多次
*/
publicclassCantStartTwice{
publicstaticvoidmain(String[]args){
Threadthread=newThread();
thread.start();
thread.start();
}
}
4、注意点:
start方法是被synchronized修饰的方法,可以保证线程安全。
由jvm创建的main方法线程和system组线程,并不会通过start来启动。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。