线程8大核心基础知识【2】-- 启动线程的正确和错误方式

本文深入探讨Java中启动线程的正确与错误方式,对比start()与run()方法,剖析线程状态与生命周期,解答常见面试问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

终于有时间写 线程8大核心基础知识【2】-- 启动线程的正确和错误方式。
跟我一起学习,一起攻破Java并发吧!
为了美好生活,为了明天,加油!

启动线程的正确和错误方式
start()和run()的比较
  • 代码演示
    在这里插入图片描述
    由此可见:Runnable调用的run打印的结果为main主线程,这不是我们想要的,我们的本意是想新创建一个线程,并启动起来。所以我们可以看到直接使用run方法带来的效果是有偏差的,Thread实现的和我们的预想结果一致
start()方法原理解读

方法含义

  • 启动新线程
    通知我们的JVM,在有空闲的情况下,启动新线程
    注:启动新线程不是我们决定的,是线程调度器决定的,所有start()方法调用后,不一定会直接运行,可能等一会才运行,也有可能很长时间不运行如:遇到饥饿的情况

一个start()会牵扯到两个线程
1.主线程
2.创建的线程

调用两次start会怎么样呢?
发现会报错,口说没意思,直接看源码吧!
在这里插入图片描述
start()源码解析

  • 启动新线程检查线程状态
    这个就是刚才报错的罪魁祸首了!如果线程状态不为0,则报异常
    在这里插入图片描述
    那0是什么呢?
    查看上面的注释的意思为:java线程状态在初始化时为0,也就是还没有启动
    在这里插入图片描述
  • 加入线程组
    在这里插入图片描述
  • 调用start0()
    被native修饰,代表不是java实现的,是有c,c++实现的
    分享一下对native的理解:start0()方法是不能直接看源码的,如果想看源码,需要去网上OpenJDK里查看,版本不同,实现可能也不同
    在这里插入图片描述
run()方法原理解读

直接调用Runnalie实现的run()方法,调用的就是普普通通的方法,和自己写的普通方法无区别,所有刚才的线程执行的线程为主线程。
所以我们要启动线程,不能调用run()方法,而是调用start方法间接调用run方法
在这里插入图片描述

常见面试问题

一个线程两次调用start()方法会出现什么情况?为什么?
答:会抛出一个异常,在start()方法最开始的时候,就会对当前的线程状态进行一个检查,如果已经执行了方法,就会抛出这个异常。
还不够,再加上线程的六个状态。
线程的状态使用一个枚举类型来描述的。这个枚举一共有6个值: NEW(新建)、RUNNABLE(运行)、BLOCKED(锁池)、TIMED_WAITING(定时等待)、WAITING(等待)、TERMINATED(终止、结束)。

既然start()方法会调用run()方法,为什么我们会调用start()方法,而不是直接调用run()方法呢?

答:因为调用start()方法才是真正启动一个线程,会经过各个线程的生命周期,如果直接调用run()方法,不过是普通的方法而已,也不会用子线程调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小梦ITSuper

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值