Java知识分享
热爱技术,分享技术

2.线程的start方法剖析:模版设计模式在Thread中的应用

在本节中,我们将分析Thread的start方法,在调用start方法之后到底进行了什么操作,通过上一遍线程的生命周期内容讲解,相信大家已经明白了,start方法启动了一个线程,并且该线程进入可执行状态,在常用的Thread应用中,我们会重写Thread的run方法,但是启动时,我们却调用了start方法,那么run方法和start方法有什么关系呢?

2.1 Thread start方法源码分析以及注意事项

public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}

start方法的源码足够简单,其实核心的部分是start0这个方法,也就是JNI方法。

private native void start0();

也就是说在start中会调用start0方法,那么重新的那个run方法,何时呗调用了呢?单从上面是看不出来任何端倪的,我们来看看官方文档怎么说的吧!

在开始执行这个线程时,JVM将会调用该线程的run方法,换言之,run方法是被JNI方法start0()调用的,仔细阅读start的源码将会总结出如下几个知识要点。

  • Thread被构造后的NEW状态,实际上threadStatus这个内部属性为0.
  • 不能两次启动Thread,否则就会出现IllegalThreadStateException异常
  • 线程启动后将会被加入到一个ThreadGroup中。
  • 一个线程生命周期结束,也是就到了TERMINATED状态,再次调用start方法是不允许的,也是就是说终止状态是没有办法回到可执行/执行中状态的。
public static void main(String[] args) {
Thread thread=new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();//启动线程
thread.start();//再次启动
}

执行上面的代码将会抛出 IllegalThreadStateException 异常,而我们将代码稍作改动,模拟一个线程的生命周期的结束,再次启动看看会发生什么:

2.线程的start方法剖析:模版设计模式在Thread中的应用插图

注意:程序同样会抛出 IllegalThreadStateException 异常,但是这2个异常的抛出却有本质区别,第一个是重复启动,只是第二次启动是不被允许的,诞生次数改线程是处于运行状态的,而第二次企图重新激活也抛出非法状态异常,但是此时没有线程,因为该线程的生灭周期以及被终结。

2.2 模版设计模式在Thread中的应用

通过上面的分析,我们意识到,线程的真正执行逻辑是在run方法中,通常我们会把run方法称为线程的执行单元,这也就回答了我们开始提出的疑问,重新run方法,用start方法启动线程,Thread中run方法的代码如下,如果我们没有使用Runnable接口对其进行构造,则可以认为Thread的run方法本身就是一个空实现: Thread中run方法的实现

@Override
public void run() {
if (target != null) {
target.run();
}
}

其实Thread和run和start就是一个比较典型的模版设计模式,父类编写算法的结构代码,子类实现逻辑细节。

打赏
本站所有资源均来源于网络,仅供学习使用,请支持正版!Java技术开源 » 2.线程的start方法剖析:模版设计模式在Thread中的应用

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册