java线程基础巩固---线程生命周期以及start方法源码剖析
上篇中介绍了如何启动一个线程,通过调用start()方法才能创建并使用新线程,并且这个start()是非阻塞的,调用之后立马就返回的,实际上它是线程生命周期环节中的一种,所以这里阐述一下线程的一个完整生命周期,里面涉及的一些状态目前还未学习到,没有关系,先有个全局观,之后都会涉及到滴。
线程的生命周期:
①、new状态:
当新建一个Thread对象时,此时的状态就是new状态:
注:这时线程还没有创建。
②、runnable状态:
当执行了Thread.start()方法之后,并不代表线程立即就能够执行,还得由CPU调度,所以此时是一个Runnable状态,也就是可以执行的状态。
③、running状态:
当CPU分配给了可运行的线程执行权时,这时线程就真正处理运行状态了:
④、blocked状态:
当运行的线程调用了wait、sleep、锁时,会从running状态变为blocked状态:
当blocked状态结束之后,比如sleep结束了,这时它不是直接就回到了running状态了,而是先回到runnable状态:
另外在running状态的线程可能被cpu把执行权切走了,也就是调度给其它线程了,这时running状态就会回到runnable状态了:
⑤、teminated状态:
最后就是线程结束状态,有几个状态都可能到线程结束状态:
- running正在运行的线程正常执行完,也就到了结束状态了:
- 在blocked状态,比如wait状态被打断了,也有可能进入结束状态:
- 在runnable状态中,如果出现一些异外情况线程死了,也有可能进入结束状态:
start()源码简单剖析:
先来看一下start()在JDK官方文档的说明:
如何理解,结合代码,这里不是用上篇中的代码为例:
所以这两个线程是:main启动线程、Read-Thread新建的线程。
接着再看文档描述:
那如果调用两次呢?
如文档描述所示,抛异常了。
那有个疑问:为啥不直接调run方法,而非得通过start()方法去启动呢?
下面试试直接调run方法:
下面来看看start()方法内部到底做了哪些事情呢?
其实这种设计技巧是一种模板方法,下面来编写一个模板方法来体会Thread的start()设计的思想:
涉及到的设计模式:
另外正常的模板方法是需要将定声明为final类型的:
当然Thread的start()方法木有将它声明为final类型:
这样子类就可以对它进行复写:
跟严格意义上的模板方法还是有些区别,不过可以思想是类似的。
线程概念总结:
这是第二篇对线程基础的巩固,涉及到了一些概念,好的学习方法是要善于总结的,所以这里对学的知识总结一下:
①、java应用程序的main函数是一个线程,是被JVM启动时调用的,线程的名字叫main。
②、实现一个线程,必须创建Thread实例,override run方法,并且调用start方法。
③、在JVM启动后,实际上有多个线程,但是至少有一个非守护进程。
④、当你调用一个线程start方法之后,此时至少有两个线程:一个是调用你的线程,另一个是执行run方法的线程【新创建的线程】。
⑤、线程的生命周期分为:new、runnable、running、blocked、teminated。
转载于:https://www.cnblogs.com/webor2006/p/7683988.html
java线程基础巩固---线程生命周期以及start方法源码剖析相关推荐
- 框架源码专题:springIOC的加载过程,bean的生命周期,结合spring源码分析
文章目录 1.BeanFactory和ApplicationContext的区别? 2. IOC与 Bean的加载过程 ①:初始化容器DefaultListableBeanFactory ②:创建读取 ...
- MediaPlayer的生命周期和缓冲策略 (源码篇)
目录 概述 必备的知识体系 MediaPlayer的api MediaPlayer的setDataSource(path: String)流程 MediaPlayer::prepare的调用流程 Me ...
- Java并发基础:了解无锁CAS就从源码分析
CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...
- Java并发基础:了解无锁CAS就从源码分析 1
CAS的全称为Compare And Swap,直译就是比较交换.是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的汇编指令,在i ...
- C语言零基础项目:生命游戏!详细思路+源码分享
每天一个C语言小项目,提升你的编程能力! 程序简介 生命游戏也叫康威生命游戏.细胞自动机.元胞自动机等. 生命游戏不需要任何玩家,它是一个二维矩形世界,这个世界中的每个方格居住着一个活细胞或为空. 一 ...
- iOS之深入解析WKWebView加载的生命周期与代理方法
一.前言 从 WebView 开始加载一条请求,到页面完整呈现这一过程发生了什么?无论是做 WebView 性能优化还是异常问题监控与排查,都离不开对WKWebView加载的生命周期与代理方法的剖析. ...
- 深入java并发包源码(三)AQS独占方法源码分析
深入java并发包源码(一)简介 深入java并发包源码(二)AQS的介绍与使用 深入java并发包源码(三)AQS独占方法源码分析 AQS 的实现原理 学完用 AQS 自定义一个锁以后,我们可以来看 ...
- Java多线程——线程的优先级和生命周期
Java多线程--线程的优先级和生命周期 摘要:本文主要介绍了线程的优先级以及线程有哪些生命周期. 部分内容来自以下博客: https://www.cnblogs.com/sunddenly/p/41 ...
- 详解java中Thread类,线程和进程的基本区别,多线程的好处,线程的五个生命周期,主线程和IDEA创建的Monitor Ctrl-Break守护线程;优雅地终止线程。死锁的产生
线程:CPU调度的最小单位:线程共享堆内存和方法区,但各自享有栈空间.进程:CPU分配资源的最小单位. 为什么需要多线程:①避免其中一个模块阻塞造成系统假死:②程序异步处理(交替执行),提高程序执行效 ...
最新文章
- 前百度主任架构师创业,两年融资千万美元,他说AI新药研发将迎来黄金十年...
- android自定义图片文本,Android 实现文字与图片的混排
- Java randomString
- vue3——ref reactive函数
- STM32程序的烧录方式 与 ISP一键下载
- 史上最通俗易懂的并查集算法详解
- Separating Pebbles数学,暴力
- Deecamp 面试翻车记录
- 【公司邮箱怎么注册】Foxmail帐户邮箱数据保存在什么地方?如何备份一个帐户?
- QQ,微信能聊天都靠它(socket)?
- python100day - day24 - DataAnalysis
- 程序员如何选择适合自己的企业?
- qt 计算字符串宽度高度
- C语言内存分布图----栈空间、堆空间
- Scrapy 豆瓣搜索页爬虫
- Direct3D显示视频
- 选定区域着色html,一种提取html页面选定区域内容的方法
- linux挂起 终端连不上吗,Linux系统11个不能不知道的终端命令
- HFirst解读和复现心得
- Debian10使用本地ISO搭建APT源
热门文章
- zabbix的日常监控-自动发现端口并监测(服务器开启的所有端口或监控指定端口)(十三)...
- vue-electron 写一个markdown文章编辑器(一)
- Java多线程超详细总结
- mysql 有两种数据库引擎发音
- NOIp #2011
- 机房收费系统学生下机结账小结
- 学习strut时遇到的问题 - Unable to compile class for JSP 错误的解决过程。
- 项目管理在企业发展中的作用及未来的发展方向—— 来自项目管理群的讨论
- 发生TM锁争用的情况
- Linux Shell常用技巧(四)