Java线程状态

简介: 线程跟人类一样拥有自己的生命周期,一条线程从创建到执行完毕的过程即是线程的生命周期,此过程可能在不同时刻处于不同的状态,线程状态正是这小节的主题,线程到底有多少种状态?不同状态之间是如何转化的?对于线程的状态的分类并没有严格的规定,只要能正确表示状态即可,如图2-5-7-1,先看其中一种状态分类,一个线程从创建到死亡可能会经历若干个状态,但在任意一个时间点线程只能处于其中一种状态,总共包含五个状态:新建(new)、可运行(runnable)、运行(running)、非可运行(not runnable)、死亡(dead)。

线程跟人类一样拥有自己的生命周期,一条线程从创建到执行完毕的过程即是线程的生命周期,此过程可能在不同时刻处于不同的状态,线程状态正是这小节的主题,线程到底有多少种状态?不同状态之间是如何转化的?

对于线程的状态的分类并没有严格的规定,只要能正确表示状态即可,如图2-5-7-1,先看其中一种状态分类,一个线程从创建到死亡可能会经历若干个状态,但在任意一个时间点线程只能处于其中一种状态,总共包含五个状态:新建(new)、可运行(runnable)、运行(running)、非可运行(not runnable)、死亡(dead)。线程的状态的转化可以由程序控制,通过某些API可以达到转化效果,例如Thread类的start、stop、sleep、suspend、resume、wait、notify等方法(stop、suspend、resume等方法因为容易引起死锁问题而早已被弃用)。

图2-5-7-1

 

l   新建(new):一个线程被创建了但未被启动就处于新建状态,即在程序中使用new MyThread();创建的线程实例就处于此状态。

l   可运行(runnable):创建的线程实例调用start()方法后便进入可运行状态,处于此状态的线程并不是说一定处于运行状态,我们在上一节多线程调度策略了解到Java多线程使用的是抢占式调度,每个可运行线程轮着获取CPU时间片,可以虚拟想象成有一个可运行线程池,start()方法把线程放进可运行线程池中,CPU按一定规则一个个执行池里的线程。

l   运行(running):当可运行线程获取到CPU执行时间片即进去了运行状态。

l   非可运行(notrunnable):运行中的线程因某种原因暂时放弃CPU的使用权,可能是因为执行了挂起、睡眠或等待等操作,在执行I/O操作时由于外部设备速度远低于处理器速度也可能导致线程暂时放弃CPU使用权,在获取对象的同步锁过程中如果同步锁先被别的线程占用同样可能导致线程暂时放弃CPU。

l   死亡(dead):线程执行完run()方法实现的任务,或因为异常导致退出任务,线程进入死亡状态后将不可再转换成其他状态。

将非可运行(not runnable)状态继续细分,如图2-5-7-2,新建、可运行、运行、死亡四个状态的定义和转化与前面的一样,重点看非可运行状态引申出来的三个状态:阻塞(blocked)、同步锁(locked)、等待(waiting)。

l   阻塞(blocked):阻塞由阻塞事件触发,线程处于阻塞状态将放弃CPU的使用权,暂时停止运行。一般线程执行了sleep()、join()方法,或发出了I/O请求,线程就将处于阻塞状态,假如sleep()执行的睡眠结束、join()执行的等待中断超时、I/O请求结束,则将重新回到可执行状态,等待分配CPU。

l   同步锁(locked):假如一个线程准备调用一个同步方法,而同步方法对应的对象正被其他线程占用,此时线程就将进入同步锁状态。实际上,Java中的每个object对象都有一个monitor,此monitor负责对同步域在并发时的独占处理,即一个线程调用某对象的同步方法时,JVM将检测改对象的monitor是否已被占用,如果没有被占用,线程则得到monitor占有权,继续执行该对象的同步方法,否则线程将被扔进一个等待线程队列排队,直到monitor被释放后,所有等待的线程继续竞争monitor占有权,抢到monitor占有权后才进入可执行状态等待CPU的分配,才有资格执行同步方法。

l   等待(waiting):运行中的线程执行了wait()方法后就进入等待状态。一个对象执行了wait()方法同样将使线程进入该对象的等待线程队列,同时它还将释放对象锁,即放弃monitor的占有权。只有在其他线程中对该对象调用notify()、notifyAll()方法时才会唤醒等待线程队列中的线程,notify是随机唤醒等待队列中的一个线程,而nofityAll则是唤醒所有等待队列中的线程,所有线程被唤醒后将对该对象的monitor占有权竞争,获取到占有权的线程才能转化为可执行状态,等待分配CPU往下执行,其他线程则继续等待。

 

图2-5-7-2





点击订购作者书籍《Tomcat内核设计剖析》




目录
相关文章
|
11月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
582 1
|
11月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
506 1
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
519 0
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
688 16
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
577 83
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
554 0
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
622 83