• 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。

  • 相关阅读:
    LayoutInflater(布局服务)
    FOTA升级
    APK安装过程及原理详解
    Context类型
    Android应用的persistent属性
    Notification(状态栏通知)详解
    Handler消息传递机制浅析
    Selenium HTMLTestRunner 无法生成测试报告的总结
    【python】远程使用rsa登录sftp,上传下载文件
    02.性能测试中的指标
  • 原文地址:https://www.cnblogs.com/webor2006/p/7683988.html
Copyright © 2020-2023  润新知