首页 > 编程语言 >JUC源码讲解:逐步解析 Thread.start() 源码

JUC源码讲解:逐步解析 Thread.start() 源码

时间:2024-03-12 21:44:06浏览次数:21  
标签:JUC Thread started start0 start 源码 线程

JUC源码讲解:逐步解析 Thread.start() 源码

抛出问题

当 new Thread() 时,线程会进入 NEW 状态,如果我们想要使用线程,就需要调用 start() 方法,那么,在使用 star() 时发生了什么?有什么需要注意的?线程是怎么一步步被创建的?跟着我一起分析源码吧!

阅读源码

为了方便讲解,我先把源码贴出来,然后逐步讲解每一步的作用

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) {
            
        }
    }
}

我们先看这个方法头部分:

public synchronized void start() {
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
}

注意到了吧,是 sync!这是为了避免被多个线程同时启动!

这个if判断,如果线程状态是 NEW,threadStatus 才等于 0,其他状态的线程是不能被 star() 的,否则会抛出线程状态异常,if 是为了避免线程被重复 start

这里提一下,init后的线程状态是NEW

看下一段,加入 ThreadGroup

group.add(this);

最后一段值得一提:

boolean started = false;
try {
    start0();
    started = true;
} finally {
    try {
        if (!started) {
            group.threadStartFailed(this);
        }
    } catch (Throwable ignore) {

    }
}

变量 started 是线程的启动状态,注意到 try 块中的 start0() 方法了吗?这是个 native 方法,目的是启动线程,在 start0() 彻底结束之前,线程的状态都是 READY!执行成功后,只要线程拿到了CPU执行权,就是 RUNNING状态

在 finally 中,通过 started 判断 start0() 是否执行成功,如果没有成功,会调用 group.threadStartFailed(this); 我们点进去这个方法里看一下吧

void threadStartFailed(Thread t) {
    synchronized(this) {
        remove(t);	// 删除该线程
        nUnstartedThreads++; // start 失败的计数器
    }
}

总结

  • start() 时为了避免线程被多次 start 而使用了 sync 和 if 。if保证非NEW状态的线程是不能被 start 的。sync方法保证不会被多个线程同时 start

  • 在 start0() 执行完全成功之前,线程的状态是 READY,执行成功后,如果线程拿到了CPU执行权,状态会变为 RUNNING,他们都是 Thread.State.class 中的 RUNNABLE 状态

  • start 失败会将线程删除,并报错给父线程

标签:JUC,Thread,started,start0,start,源码,线程
From: https://www.cnblogs.com/acdongla/p/18069392

相关文章

  • JUC源码讲解:逐步解析 Thread.init() 源码
    #JUC源码讲解:逐步解析Thread.init()源码抛出问题我们在newThread()时,init()方法便会自动调用,用来创建这个线程。那么,创建线程时都发生了什么事?子线程与父线程有何关系?线程是怎么创建的?juc怎么选择ThreadGroup?让我们从源码中寻找答案吧!查看源码privatevoidini......
  • Java项目源码基于springboot的家政服务平台的设计与实现
    大家好我是程序员阿存,在java圈的辛苦码农。辛辛苦苦板砖,今天要和大家聊的是一款Java项目源码基于springboot的家政服务平台的设计与实现,项目源码以及部署相关请联系存哥,文末附上联系信息。项目源码:Java基于springboot的家政服务平台的设计与实现.rar资源-CSDN文库项目简介:......
  • JUC源码讲解:线程状态转换
    JUC源码讲解:线程状态转换抛出问题一个线程,有七种(也可以说是六种)状态,究竟是哪七种呢?在什么条件下,线程会进入一个状态,又在什么条件下,线程转而进入另一种状态呢?下面我们从源码角度看一下线程的状态转换观察源码我们进去Thread.State.class中,可以看到,线程状态由一个enum定义......
  • Python基于微博的舆论分析,舆论情感分析可视化系统(V5.0),附源码
    博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w+、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......
  • pdf.js源码解析-PDF文件的结构
    为了了解pdf.js源码的详细结构和功能,先来看看PDF的文件结构,然后才能知道pdf.js中的代码是如何解析并且为何这样操作PDF文件的。PDF文件基本是由header、body、trailer组成。header包含了这个PDF的信息,比如PDF的版本,创建时间,以及作者等。body包含了PDF文件的实际内容,比如文本,图片,......
  • Hive-源码分析一条hql的执行过程
    一、源码下载 下面是hive官方源码下载地址,我下载的是hive-3.1.3,那就一起来看下吧https://dlcdn.apache.org/hive/hive-3.1.3/apache-hive-3.1.3-src.tar.gz二、上下文<Hive-源码带你看hive命令背后都做了什么>博客中已经讲到了hive命令执行后会一直循环处理控制台输入的hq......
  • 【短剧小程序开发】费用从20元送源码到20万定制到底有什么区别?
    网络微短剧无疑是2024年最火热的蓝海项目之一。2023年国内微短剧总量已达373.9亿元,可知道全年电影总票房才549亿元。短剧的市场总量超过电影票房指日可待,预计2027年短剧总量可达1000亿元。稍微关注短剧赛道的朋友就会发现,23年至今不断会有某某短剧上线当日充值超2000万等等新......
  • [Rust] Thread 3: move keyword to resolve borrowing problem for closure
    Weofteruse movewithclosurespassedto thread::spawnbecasetheclosurewillthentakeownershipofthevaluesitusesfromtheenvironment,thustransferringowershopofthosevaluesfromonethreadtoanother. Thefollowingcodewon'twork:use......
  • 如何在Visual Studio中调试.NET源码
    今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。我一般的做法是先判断是否为null,再判断Count。看了一下Count的源码如下:1[__DynamicallyInvokable]2publicintCount3{4[__DynamicallyInvokable]5get6......
  • RocketMQ为什么这么快?我从源码中扒出了10大原因!
    大家好,我是三友~~RocketMQ作为阿里开源的消息中间件,深受广大开发者的喜爱而这其中一个很重要原因就是,它处理消息和拉取消息的速度非常快那么,问题来了,RocketMQ为什么这么快呢?接下来,我将从以下10个方面来探讨一下RocketMQ这么快的背后原因如果你对RocketMQ还不了解,可以从公众......