Java线程的6种状态

线程的概念,以及线程的创建方式,见我之前写的博文

本篇文章主要讲Java线程的6种状态

6种状态:初始状态(new) 、可运行状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)、死亡状态(Dead)、等待队列

初始状态(New)
进程刚创建,未调用new Thread().start()方法时的状态,进程创建方式

可运行状态(Runnable)
在创建线程并调用start()方法之后,获得CPU运行时间之前的状态

进入Runnable状态的方式:

  1. 调用线程的start()方法
  2. 当前线程sleep()方法结束
  3. 其他线程join()结束
  4. 等待用户输入完毕(阻塞式IO,拿到IO结果后)
  5. 当前线程拿到所需锁
  6. 当前线程时间片耗尽
  7. 调用当前线程的yield()方法

运行中状态Running
获得CPU运行时间后,运行中的状态

进入Running状态的方式(唯一):

  1. 操作系统的线程调度程序,从可运行状态的线程池中,选出当前线程去执行;

阻塞状态Blocked
运行中的线程,可以会由于各种原因进入到阻塞状态。如调用sleep()方法让线程睡眠,调用wait()方法让线程等待,调用join()、suspend()方法(已弃用)或者阻塞式IO。

进入阻塞状态的方式:

  1. 当前线程调用sleep()方法
  2. 当前线程执行过程中,调用了其他线程的join()方法,当前线程进入阻塞状态
  3. 等待阻塞式IO时

死亡状态Dead
无论是正常退出(run()方法执行完毕),还是抛出了未捕获的异常,都会导致线程进入Dead状态。
或者是主线程main方法执行完毕
在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常

线程的状态流转图

线程状态流转图

线程睡眠:sleep()方法

线程睡眠,指的是让当前线程暂停执行,等到指定时间后再恢复执行(Runnable状态)

  1. 线程睡眠会交出CPU,让给其他线/进程执行
  2. sleep()方法不会释放锁,即当前线程持有某个对象锁时,即使调用sleep()方法其他线程也无法访问这个对象。
  3. 调用sleep(),当前线程从Running到blocked,sleep结束,从blocked到Runnable
public static native void sleep(long millis) throws InterruptedException;

线程让步:yield()方法

线程让步,指的是让当前线程暂停执行,并执行其他线程
与sleep()的区别在于

  1. yield()方法无法控制具体交出CPU的时间
  2. yield()方法只能让拥有相同优先级的线程获得CPU执行的机会
  3. yield()方法让当前线程进入Runnable状态

yield()方法:

public static native void yield();

等待线程终止:join()方法

等待线程终止,指的是:主线程中调用该方法,就会让调用该方法的线程先执行,等执行结束后,再回到主线程继续执行。(即等待,调用join()方法的线程执行完毕后,再执行)

join()方法:

public final void join() throws InterruptedException {//join带参数指的是等待的超时时间,为0代表永久等待join(0);}

wait()方法

obj.wait(),当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout)timeout时间到自动唤醒

public final void wait() throws InterruptedException {}public final native void wait(long timeout) throws InterruptedException;

notify()方法

obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程

public final native void notify();public final native void notifyAll();

线程停止的3种方式

1):设置标志位,让线程正常停止

class MyThread1 extends Thread {private boolean flag = false;@Overridepublic void run() {int i=0;while (!flag) {System.out.println("线程循环执行次数:"+i);}}
}

2):使用stop方法强制线程停止,不安全,已废弃!

stop方法:

@Deprecatedpublic final void stop() {}

为什么stop()不安全?

因为stop()会解除相应线程持有的所有锁,并且当在线程对象上执行stop方法时,会立即停止该线程

比如当正在执行如下同步方法时,执行到x=10,线程调用了stop()方法,那就会进入不一致的状态,所以线程不安全

public synchronized void f() {x =10;y =20;
}

3):调用interrupt()方法

调用Thread类的interrupted()方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并根据线程状态决定是否抛出异常。因此,通过interrupted()方法真正实现线程的中断原理是 :开发人员根据中断标志的具体值来决定如何退出线程。

interrupt()方法

public void interrupt() {}

拓展:

为什么notify(), wait()等函数定义在Object中,而不是Thread中

Object中的wait(), notify()等函数,和synchronized一样,会对“对象的同步锁”进行操作。

wait()会使“当前线程”等待,因为线程进入等待状态,所以线程应该释放它锁持有的“同步锁”,否则其它线程获取不到该“同步锁”而无法运行!
OK,线程调用wait()之后,会释放它锁持有的“同步锁”;而且,根据前面的介绍,我们知道:等待线程可以被notify()或notifyAll()唤醒。现在,请思考一个问题:notify()是依据什么唤醒等待线程的?或者说,wait()等待线程和notify()之间是通过什么关联起来的?答案是:依据“对象的同步锁”。

负责唤醒等待线程的那个线程(我们称为“唤醒线程”),它只有在获取“该对象的同步锁”(这里的同步锁必须和等待线程的同步锁是同一个),并且调用notify()或notifyAll()方法之后,才能唤醒等待线程。虽然,等待线程被唤醒;但是,它不能立刻执行,因为唤醒线程还持有“该对象的同步锁”。必须等到唤醒线程释放了“对象的同步锁”之后,等待线程才能获取到“对象的同步锁”进而继续运行。

总之,notify(), wait()依赖于“同步锁”,而“同步锁”是对象锁持有,并且每个对象有且仅有一个!这就是为什么notify(), wait()等函数定义在Object类,而不是Thread类中的原因。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C. Goodbye Souvenir(CDQ 或 树套树)

C. Goodbye Souvenir ∑iLRi−preAi[preAi≥L]\sum\limits_{i L} ^{R} i - pre_{A_i} [pre_{A_i} \geq L]iL∑R​i−preAi​​[preAi​​≥L],进一步考虑即∑i−preAi[i≤R,preAi≥L]\sum i - pre_{A_i}[i \leq R, pre_{A_i} \geq L]∑i−preAi​​[i≤R,preAi​​…

.NET Core 微信小程序支付——(统一下单)

最近公司研发了几个电商小程序,还有一个核心的电商直播,只要是电商一般都会涉及到交易信息,离不开支付系统,这里我们统一实现小程序的支付流程(与服务号实现步骤一样)。目录1、开通小程序的支付能力2、商户…

P4768 [NOI2018] 归程(kruskal 重构树)

P4768 [NOI2018] 归程 给定一个nnn个点,mmm条边的无向联通图,边的描述为[u,v,l,a][u, v, l, a][u,v,l,a],表示uuu,vvv连有一条长度为lll,海拔为aaa的边, 有QQQ个询问,每次给出一个出发点uuu和…

用.NET写“算命”程序

前言“算命”,是一种迷信,我父亲那一辈却执迷不悟,有时深陷其中,有时为求一“上上签”,甚至不惜重金,向“天神”保佑。我曾看到过有些算命网站,可以根据人的生辰八字,来求得这个人一…

Java线程调度

线程调度指的是系统为线程分配CPU使用权的方式。主要有协同式线程调度和抢占式线程调度。 协同式线程调度(Cooperative Threads-Scheduling) 在多线程系统中,线程的执行时间由线程自身控制,执行结束后要主动通知系统切换到另一线…

#3551. [ONTAK2010]Peaks加强版(kruskal 重构树 + 主席树)

#3551. [ONTAK2010]Peaks加强版 我们要求从一个点出发经过困难值小于等于xxx的路径所能到达的山峰中第kkk高的是什么。 考虑按照边权升序,建议kruskalkruskalkruskal重构树,然后倍增向上跳,找到困难值小于等于xxx的深度最小的节点uuu&#…

ASP.NET Core 3.0 迁移避坑指南

一.前言.NET Core 3.0将会在 .NET Conf 大会上正式发布,截止今日发布了9个预览版,改动也是不少,由于没有持续关注,今天将前面开源的动态WebApi项目迁移到.NET Core 3.0还花了不少时间踩坑,给大家分享一下我在迁移过程中…

kruskal 重构树(讲解 + 例题)

kruskal重构树 如何建树 模仿kruskalkruskalkruskal,先将所有边排序。 依次遍历每一条边,如果这条边的两个节点(u,vu, vu,v)不在同一个连通块里面, 则新建一个nodenodenode节点,更新fa[u]fa[v]nodefa[u…

打不死我的,终将使我强大!DevOps黑客马拉松参赛心得

(IDCF DevOps黑客马拉松到底是个啥活动?)长得丑活得久、长得帅也惹人爱!大家好,我是刘威。隆正信息的业务架构师-花名逸云。非常荣幸可以参加在北京举办的第一届DevOps黑客马拉松比赛。黑客马拉松不是突然冒出来的&…

Java线程池面试题

1、什么是线程池 java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。 假设一个服…

F. Cheap Robot(kruskal 重构树)

F. Cheap Robot 给定一个无向连通图,每条边有边权,路过需要消耗对应的电量(边权),有kkk个中心点, 问从a−>ba-> ba−>b,我们最少需要带多少电,设最小为CCC,当…

「标签管理」使用标签管理有道云笔记资料

因着大家对文件标签化比较高难道,需要熟悉一个标签工具软件,所以今天暂时来介绍个简单一些的网络资料的标签化管理,使用有道云笔记作为落地工具,同理在OneNote、印象笔记上原理类似。有道云笔记免费功能够用为了选择哪个笔记产品&…

JDK线程池实现

参见: https://www.cnblogs.com/trust-freedom/p/6594270.html http://ifeve.com/java-threadpool/ https://blog.csdn.net/u010963948/article/details/80573898 https://blog.csdn.net/moakun/article/details/80606029 https://www.cnblogs.com/liuzhihu/p/81773…

Problem G. Pandaria(线段树合并 + Kruskal 重构树)

Problem G. Pandaria 给定一个有nnn条边的无向连通图,每条边有对应的边权,每个点有一个颜色, 问从一个点出发,经过不超过www的边权,所能到达的点中,颜色出现次数做多且颜色编号最小的是什么颜色。 不超过…

我如何吸引Elastic创始人一起对高并发写入进行优化?

导语:在腾讯金融科技数据应用部的全民 BI 项目里,我们每天面对超过 10 亿级的数据写入,提高 ES 写入性能迫在眉睫,在最近的一次优化中,有幸参与到了 Elasticsearch 开源社区中。背景为了更便捷地分析数据,腾…

Java线程安全

Java 线程安全 什么是线程安全? 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。 一:基本概念 共享资源:能够被多个线程同时访问的资源竞态条件:当两个线程竞争统…

P4899 [IOI2018] werewolf 狼人(kruskal 重构树 + 主席树)

P4899 [IOI2018] werewolf 狼人 给定一个有nnn个点mmm条边的无向图,有QQQ个询问 每次输入S,E,L,RS, E, L, RS,E,L,R,表示你在SSS点出发,要到EEE点,且初始时你是人形态,你只能走[L,n][L, n][L,n]的点, 但…

微软+开源,那些亲爱的以及热爱的

微软 Reactor 社区空间开幕式暨 Azure Meetup 社区活动已于9月7日在上海圆满结束!但是…如何构建一个可持续发展的社区未来的路,仍然很长...你应该知道的微软 Reactor微软 Reactor 是微软为构建开发者社区而提供的一个社区空间,以“予力多元…

Java线程问题问答

1、多线程的作用? 发挥多核CPU的优势,提高效率防止阻塞便于建模:将一个任务拆分成多个子任务,分别建立程序模型 2:平时项目中使用锁和synchronized比较多,而很少使用volatile,难道就没有保证可见…

ASP.NET Core 2.2 项目升级至 3.0 备忘录

.NET Core 3.0及ASP.NET Core 3.0 前瞻ASP.NET Core 3.0 迁移避坑指南将 ASP.NET Core 2.2 迁移至 ASP.NET Core 3.0 需要注意的地方记录在这篇随笔中。TargetFramework 改为 netcoreapp3.0 <TargetFramework>netcoreapp3.0</TargetFramework>从 Web 项目&#xff…