线程的状态 ﹏ヽ暗。殇╰゛Y 2023-09-27 13:09 111阅读 0赞 ![在这里插入图片描述][2d280b0176ba4be2ae9f37daba7f7c5d.gif_pic_center] #### 文章目录 #### * 一、线程的所有状态 * 二、状态转换 * 三、多线程初体验 ## 一、线程的所有状态 ## 状态是针对当前线程调度情况所描述的,又因为线程是调度的基本单位,所以我们所谈到的状态都是线程的属性。在java里对线程的状态,进行了一个更细的划分。 ![在这里插入图片描述][358254b369544de89dc8ce4e2aeb4b7c.png] 我们可以发现: 线程的状态是一个枚举类型 Thread.State 我们可以遍历一下线程状态枚举 public class Test { public static void main(String[] args) { for(Thread.State state : Thread.State.values()) { System.out.println(state); } } } ![在这里插入图片描述][92206951288a4d3688e2ceb8f40cfb62.png] <table> <thead> <tr> <th>状态</th> <th>意义</th> </tr> </thead> <tbody> <tr> <td>NEW</td> <td>创建了Thread对象,但是还没有调用start(操作系统内核还没有创建PCB)</td> </tr> <tr> <td>TERMINATED</td> <td>操作系统内核的PCB已经执行完了,但Thread对象还存在</td> </tr> <tr> <td>RUNNABLE</td> <td>可运行的,可分为:正在工作 和 即将开始工作</td> </tr> <tr> <td>WATING</td> <td>表示不同原因的阻塞(表示线程PCB处在阻塞队列)</td> </tr> <tr> <td>TIME_WAITING</td> <td>表示不同原因的阻塞(表示线程PCB处在阻塞队列)</td> </tr> <tr> <td>BLOCKED</td> <td>表示不同原因的阻塞(表示线程PCB处在阻塞队列)</td> </tr> </tbody> </table> ## 二、状态转换 ## ![在这里插入图片描述][0f08f07714264e7eb2c01abc5a06f94c.png] 这是一个很复杂的状态转换图,但实际的状态转换是清晰明了的 ![在这里插入图片描述][ceabb6cbd7bb45d792cd3cea2b880687.png] NEW状态: 线程对象创建完成,没有start()的状态。 TERMINATED状态: run()执行结束的状态。 public static void main(String[] args) throws InterruptedException { Thread t = new Thread(() -> { for (int i = 0; i < 1000; i++) { } }); System.out.println("start之前的状态: "+t.getState()); t.start(); t.join(); System.out.println("run之后的状态: "+t.getState()); } ![在这里插入图片描述][8f2c5a3d93394ada80de4b25ff941599.png] TERMINATED状态实际是没什么意义的,因为一旦内核里的线程PCB销毁了,代码里的Thread对象t也没什么实际意义了,只是为了把t对象标识为" 无效状态 ",因为**一个线程,只能start一次** RUNNABLE状态: 可运行的,可分为两种: 1. 在就绪队列里,随时可去CPU执行 2. 正在CPU执行 public static void main(String[] args) throws InterruptedException { Thread t = new Thread(() -> { for (int i = 0; i < 1000; i++) { } }); System.out.println("start之前的状态: "+t.getState()); t.start(); System.out.println("t正在运行的状态: "+t.getState()); t.join(); System.out.println("run之后的状态: "+t.getState()); } ![在这里插入图片描述][027940d742244251917196cbde940ae0.png] 我们可以发现RUNNABLE状态,我们之所以可以看到这个状态,因为我们的线程没有写sleep,join等方法 ![在这里插入图片描述][d31f49b950c444efae35e368c6f1c365.png] 当我们在线程run方法加了sleep方法时,我们看到的状态是RUNNABLE还是TIME\_WAITING (完全取决于我们t线程当时运行在什么情况) for (int i = 0; i < 100; i++) { System.out.println("t正在运行的状态: "+t.getState()); } 我们在start方法之后循环获取100次线程状态观察一下 ![在这里插入图片描述][db499c58054a45238f392275821584f2.png] 我们这里观察到的交替状态完全取决于系统里的调度操作,获取状态这一瞬间线程是sleep,还是正在执行。 WAITING和BLOCKED也是类似的,不过触发条件不同,一个是wait,join,另一个是synchronized加锁等。 ## 三、多线程初体验 ## 学习了这么多线程的知识,相信很多同学会问,多线程的意义到底是什么呢? 这里我们来看一段代码,单线程和多线程之间的差距。 场景: 我们需要给两个变量,各自自增100000w次。 **单线程:** public static void main(String[] args) { single(); } public static void single() { long start = System.currentTimeMillis(); int a = 0; for (int i = 0; i < 10_0000_0000L; i++) { a++; } int b = 0; for (int i = 0; i < 10_0000_0000L; i++) { b++; } long end = System.currentTimeMillis(); System.out.println("单线程执行时间为: "+(end - start)); } ![在这里插入图片描述][bdf1a9ba6edb4ee5ba4fc9e2cf5c01d3.png] ![在这里插入图片描述][e2cb02cdb47b4aa2a5cb940c27926056.png] ![在这里插入图片描述][bed1de67cf5d4abca42e71b2aca1a333.png] 大概平均时间700多ms **多线程:** public static void main(String[] args) { multith(); } public static void multith() { Thread t1 = new Thread(() ->{ for (int i = 0; i < 10_0000_0000L; i++) { int a = 0; a++; } }); Thread t2 = new Thread(() ->{ for (int i = 0; i < 10_0000_0000L; i++) { int b = 0; b++; } }); long start = System.currentTimeMillis(); t1.start(); t2.start(); long end = System.currentTimeMillis(); System.out.println("多线程执行时间为: "+(end - start)); } ![在这里插入图片描述][72e2ef7fb85341a993ac12a917ebb0c6.png] 为什么我们会出现0ms的情况,即使我们多线程再快,也不至于0ms ![在这里插入图片描述][0501ec62fa244c2eb10860e5cce5b47e.png] 我们只是启动了t1,t2线程,并没有等到t1,t2执行结束(好比运动会裁判在运动员刚起跑就停止秒表是类似的,我们要想记录真正的时间,就得等运动员冲线)线程执行结束才可以。 public static void multith() { Thread t1 = new Thread(() ->{ for (int i = 0; i < 10_0000_0000L; i++) { int a = 0; a++; } }); Thread t2 = new Thread(() ->{ for (int i = 0; i < 10_0000_0000L; i++) { int b = 0; b++; } }); long start = System.currentTimeMillis(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("多线程执行时间为: "+(end - start)); } ![在这里插入图片描述][ae271d81bd2045f3a4ccb09e7d3c0433.png] 我们这里的join的作用是让t1,t2线程执行结束,再去执行main函数。 ![在这里插入图片描述][000b631cdfab43769f2978f749de4544.png] ![在这里插入图片描述][c1bb8b3751344ea8bd5fd7ebaa90a530.png] ![在这里插入图片描述][4d2ccacbbd4c4f8db9bc3b2fe21c0122.png] 我们可以发现多线程比多线程执行的时间缩短的很明显(700 -> 400) 为什么不是刚好缩短一半? 多线程之所以能快,是因为多线程能够更充分的利用到多核心cpu的资源,但是此处我们并不是保证t1,t2是并行执行,而不是并发执行。 [2d280b0176ba4be2ae9f37daba7f7c5d.gif_pic_center]: https://img-blog.csdnimg.cn/2d280b0176ba4be2ae9f37daba7f7c5d.gif#pic_center [358254b369544de89dc8ce4e2aeb4b7c.png]: https://img-blog.csdnimg.cn/358254b369544de89dc8ce4e2aeb4b7c.png [92206951288a4d3688e2ceb8f40cfb62.png]: https://img-blog.csdnimg.cn/92206951288a4d3688e2ceb8f40cfb62.png [0f08f07714264e7eb2c01abc5a06f94c.png]: https://img-blog.csdnimg.cn/0f08f07714264e7eb2c01abc5a06f94c.png [ceabb6cbd7bb45d792cd3cea2b880687.png]: https://img-blog.csdnimg.cn/ceabb6cbd7bb45d792cd3cea2b880687.png [8f2c5a3d93394ada80de4b25ff941599.png]: https://img-blog.csdnimg.cn/8f2c5a3d93394ada80de4b25ff941599.png [027940d742244251917196cbde940ae0.png]: https://img-blog.csdnimg.cn/027940d742244251917196cbde940ae0.png [d31f49b950c444efae35e368c6f1c365.png]: https://img-blog.csdnimg.cn/d31f49b950c444efae35e368c6f1c365.png [db499c58054a45238f392275821584f2.png]: https://img-blog.csdnimg.cn/db499c58054a45238f392275821584f2.png [bdf1a9ba6edb4ee5ba4fc9e2cf5c01d3.png]: https://img-blog.csdnimg.cn/bdf1a9ba6edb4ee5ba4fc9e2cf5c01d3.png [e2cb02cdb47b4aa2a5cb940c27926056.png]: https://img-blog.csdnimg.cn/e2cb02cdb47b4aa2a5cb940c27926056.png [bed1de67cf5d4abca42e71b2aca1a333.png]: https://img-blog.csdnimg.cn/bed1de67cf5d4abca42e71b2aca1a333.png [72e2ef7fb85341a993ac12a917ebb0c6.png]: https://img-blog.csdnimg.cn/72e2ef7fb85341a993ac12a917ebb0c6.png [0501ec62fa244c2eb10860e5cce5b47e.png]: https://img-blog.csdnimg.cn/0501ec62fa244c2eb10860e5cce5b47e.png [ae271d81bd2045f3a4ccb09e7d3c0433.png]: https://img-blog.csdnimg.cn/ae271d81bd2045f3a4ccb09e7d3c0433.png [000b631cdfab43769f2978f749de4544.png]: https://img-blog.csdnimg.cn/000b631cdfab43769f2978f749de4544.png [c1bb8b3751344ea8bd5fd7ebaa90a530.png]: https://img-blog.csdnimg.cn/c1bb8b3751344ea8bd5fd7ebaa90a530.png [4d2ccacbbd4c4f8db9bc3b2fe21c0122.png]: https://img-blog.csdnimg.cn/4d2ccacbbd4c4f8db9bc3b2fe21c0122.png
相关 线程的状态 目录 1.线程状态的种类 2.线程的状态图 3.状态的详细说明 -------------------- 1.线程状态的种类 初始(NEW):新建一个线程,但还 落日映苍穹つ/ 2024年03月25日 20:08/ 0 赞/ 33 阅读
相关 线程状态和线程池状态 线程状态 有六种状态; 新创建(NEW) 可运行(Runnable) 锁阻塞(Blocked) 无线等待(Waiting) 计时等待(Timed Wa 桃扇骨/ 2023年10月06日 14:08/ 0 赞/ 17 阅读
相关 线程的状态 ![在这里插入图片描述][2d280b0176ba4be2ae9f37daba7f7c5d.gif_pic_center] 文章目录 一、线程的所有状态 二 ﹏ヽ暗。殇╰゛Y/ 2023年09月27日 13:09/ 0 赞/ 112 阅读
相关 线程的状态 我百度了一下,有说三种,有说四种,有说五种,有说六种,还有说七种。下边列出六种的说法,六种见的比较多。 这是线程的六种状态 1. 初始(NEW):新创建了一个线程对象, 墨蓝/ 2023年06月07日 05:37/ 0 赞/ 3 阅读
相关 线程的状态 线程的状态 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解。 线程从创建到最终的消亡,要 Dear 丶/ 2022年09月24日 14:22/ 0 赞/ 170 阅读
相关 线程的状态 要想实现多线程,必须在主线程中创建新的线程对象。任何线程一般具有5种状态, 即 创建、就绪、运行、阻塞、终止。线程状态的转移与方法之间的关系如图所示 ![这里写图片描述][ 心已赠人/ 2022年07月21日 02:49/ 0 赞/ 203 阅读
相关 线程的状态 线程对象在不同的运行时期有不同的状态,状态信息就存在于State枚举类中, \ public static enum Thread.State extends En 秒速五厘米/ 2022年06月08日 00:46/ 0 赞/ 204 阅读
相关 线程的状态 Thread源码里定义了6种状态,如下: \ A thread state. A thread can be in one of the follo 川长思鸟来/ 2022年02月15日 13:47/ 0 赞/ 247 阅读
相关 线程的状态 线程共有六种状态 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9 妖狐艹你老母/ 2021年12月19日 00:21/ 0 赞/ 354 阅读
相关 线程的状态 RUNNABLE这个名字很具有欺骗性,很容易让人误以为处于这个状态的线程正在运行。事实上,这个状态只是表示,线程是可运行的。我们已经无数次提到过,一个单核CPU在同一时刻... 朱雀/ 2020年05月12日 15:57/ 0 赞/ 898 阅读
还没有评论,来说两句吧...