上篇中介绍了如何启动一个线程,通过调用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。

java线程基础巩固---线程生命周期以及start方法源码剖析的更多相关文章

  1. Java并发基础:了解无锁CAS就从源码分析

    https://segmentfault.com/a/1190000015881923

  2. java多线程(2)---生命周期、线程通讯

    java生命周期.线程通讯 一.生命周期 有关线程生命周期就要看下面这张图,围绕这张图讲解它的方法的含义,和不同方法间的区别.    1.yield()方法 yield()让当前正在运行的线程回到就绪 ...

  3. [转]Java 对象锁-synchronized()与线程的状态与生命周期

      线程的状态与生命周期 Java 对象锁-synchronized() ? 1 2 3 4 synchronized(someObject){   //对象锁 } 对象锁的使用说明: 1.对象锁的返 ...

  4. Java多线程——线程的优先级和生命周期

    Java多线程——线程的优先级和生命周期 摘要:本文主要介绍了线程的优先级以及线程有哪些生命周期. 部分内容来自以下博客: https://www.cnblogs.com/sunddenly/p/41 ...

  5. ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!

    前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...

  6. Java Servlet系列之Servlet生命周期

    Servlet生命周期定义了一个Servlet如何被加载.初始化,以及它怎样接收请求.响应请求,提供服务.在讨论Servlet生命周期之前,先让我们来看一下这几个方法: 1. init()方法 在Se ...

  7. Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程

    下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...

  8. Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

    Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程:    1.线程是一堆指令,是操作系统调度 ...

  9. 014-多线程-基础-Exchanger-行线程间的数据交换

    一.简介 Exchanger类允许在两个线程之间定义同步点,当两个线程都到达同步点时,它们交换数据.也就是第一个线程的数据进入到第二个线程中,第二线程的数据进入到第一个线程中. Exchanger可以 ...

随机推荐

  1. 关于LuckyE博客的前言

    第一次开始尝试怎么写博客,也不知道写点什么好...... 开始写博客的原因其实很多,主要原因是因为最近考出cisp-pte证书,然后前几天电话面试某比较有名的安全公司(x盟)的渗透测试工程师实习生被撸 ...

  2. 第8课.第一个ARM裸板程序(点亮led)及申引

    1.原理图 2.芯片手册 3.几条汇编代码 1.ldr:读内存 ldr R0, [R1] 假设R1的值是x,读取地址x上的数据(4字节),保存到R0中 ldr R0, =0x12345678 (4字节 ...

  3. Information retrieval (IR class1)

    1. 什么是IR? IR与数据库的区别? 答:数据库是检索结构化的数据,例如关系数据库:而信息检索是检索非结构化/半结构化的数据,例如:一系列的文本.信息检索是属于NLP(自然语言处理)里面最实用的一 ...

  4. 【转帖】龙芯将两款 CPU 核开源,这意味着什么?

    龙芯将两款 CPU 核开源,这意味着什么? https://www.oschina.net/news/78316/loongson-open-source-two-cpu-core 文章挺不错的 也讲 ...

  5. [转帖]iphone11的部分参数 UX

    iPhone 11将于9月11号凌晨发布 靠谱爆料在这 https://www.cnbeta.com/articles/tech/884199.htm iphone的分辨率 非常高.. iphone ...

  6. Spring Boot CommandLineRunner的使用

    1. 说明 程序在启动完成的时候需要去处理某些业务,因此Spring Boot程序中需要去实现CommandLineRunner接口. 2. CommandLineRunner方法执行顺序 程序启动后 ...

  7. springboot问题

    1.导入数据库jar包后,配置好,发现报错 数据库连接不成功  加上@SpringBootApplication(exclude = DataSourceAutoConfiguration.class ...

  8. python 分支语句 等值判断 逻辑运算符

    # 分支语句age = 233if age < 18: print('您还未满18岁,禁止入内')elif age > 18 and age < 60: print("欢迎 ...

  9. oracle用户解锁,rename管理

    ---查看命令:用户默认表空间 SYS@ACE >select username,default_tablespace,temporary_tablespace,created from dba ...

  10. 怎样查看Redis的版本号

    Q: 怎样查看Redis版本 A: 下面两条命令都可以查看redis 版本: redis-server --version redis-server -v