首页 技术 正文
技术 2022年11月11日
0 收藏 903 点赞 4,378 浏览 1331 个字

上篇中介绍了如何启动一个线程,通过调用start()方法才能创建并使用新线程,并且这个start()是非阻塞的,调用之后立马就返回的,实际上它是线程生命周期环节中的一种,所以这里阐述一下线程的一个完整生命周期,里面涉及的一些状态目前还未学习到,没有关系,先有个全局观,之后都会涉及到滴。

线程的生命周期:

①、new状态:

当新建一个Thread对象时,此时的状态就是new状态:

java线程基础巩固—线程生命周期以及start方法源码剖析

注:这时线程还没有创建。

②、runnable状态:

当执行了Thread.start()方法之后,并不代表线程立即就能够执行,还得由CPU调度,所以此时是一个Runnable状态,也就是可以执行的状态。

java线程基础巩固—线程生命周期以及start方法源码剖析

③、running状态:

当CPU分配给了可运行的线程执行权时,这时线程就真正处理运行状态了:

java线程基础巩固—线程生命周期以及start方法源码剖析

④、blocked状态:

当运行的线程调用了wait、sleep、锁时,会从running状态变为blocked状态:

java线程基础巩固—线程生命周期以及start方法源码剖析

当blocked状态结束之后,比如sleep结束了,这时它不是直接就回到了running状态了,而是先回到runnable状态:

java线程基础巩固—线程生命周期以及start方法源码剖析

另外在running状态的线程可能被cpu把执行权切走了,也就是调度给其它线程了,这时running状态就会回到runnable状态了:

java线程基础巩固—线程生命周期以及start方法源码剖析

⑤、teminated状态:

最后就是线程结束状态,有几个状态都可能到线程结束状态:

  • running正在运行的线程正常执行完,也就到了结束状态了:
    java线程基础巩固—线程生命周期以及start方法源码剖析
  • 在blocked状态,比如wait状态被打断了,也有可能进入结束状态:
    java线程基础巩固—线程生命周期以及start方法源码剖析
  • 在runnable状态中,如果出现一些异外情况线程死了,也有可能进入结束状态:
    java线程基础巩固—线程生命周期以及start方法源码剖析

start()源码简单剖析:

先来看一下start()在JDK官方文档的说明:

java线程基础巩固—线程生命周期以及start方法源码剖析

如何理解,结合代码,这里还是用上篇中的代码为例:
java线程基础巩固—线程生命周期以及start方法源码剖析

java线程基础巩固—线程生命周期以及start方法源码剖析

所以这两个线程是:main启动线程、Read-Thread新建的线程。

接着再看文档描述:

java线程基础巩固—线程生命周期以及start方法源码剖析

那如果调用两次呢?

java线程基础巩固—线程生命周期以及start方法源码剖析

java线程基础巩固—线程生命周期以及start方法源码剖析

如文档描述所示,抛异常了。

那有个疑问:为啥不直接调run方法,而非得通过start()方法去启动呢?

下面试试直接调run方法:

java线程基础巩固—线程生命周期以及start方法源码剖析

java线程基础巩固—线程生命周期以及start方法源码剖析

下面来看看start()方法内部到底做了哪些事情呢?

java线程基础巩固—线程生命周期以及start方法源码剖析

java线程基础巩固—线程生命周期以及start方法源码剖析

其实这种设计技巧是一种模板方法,下面来编写一个模板方法来体会Thread的start()设计的思想:

涉及到的设计模式:

java线程基础巩固—线程生命周期以及start方法源码剖析

java线程基础巩固—线程生命周期以及start方法源码剖析

另外正常的模板方法是需要将定声明为final类型的:

java线程基础巩固—线程生命周期以及start方法源码剖析

当然Thread的start()方法木有将它声明为final类型:

java线程基础巩固—线程生命周期以及start方法源码剖析

这样子类就可以对它进行复写:

java线程基础巩固—线程生命周期以及start方法源码剖析

跟严格意义上的模板方法还是有些区别,不过可以思想是类似的。

线程概念总结:

这是第二篇对线程基础的巩固,涉及到了一些概念,好的学习方法是要善于总结的,所以这里对学的知识总结一下:

①、java应用程序的main函数是一个线程,是被JVM启动时调用的,线程的名字叫main。

②、实现一个线程,必须创建Thread实例,override run方法,并且调用start方法。

③、在JVM启动后,实际上有多个线程,但是至少有一个非守护进程。

④、当你调用一个线程start方法之后,此时至少有两个线程:一个是调用你的线程,另一个是执行run方法的线程【新创建的线程】。

⑤、线程的生命周期分为:new、runnable、running、blocked、teminated。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,499
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,913
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,746
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,503
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,142
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,305