java并发编程-线程生命周期
线程生命周期
现代操作系统在运行一个程序时,会为其创建一个进程。例如,启动一个Java程序,操作系统就会创建一个Java进程。现代操作系统调度的最小单元是线程,也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,让使用者感觉到这些线程在同时执行。
CPU再切换线程是会导致线程存在各种状态,线程从创建到死亡其中存在不同的生命状态;本文将对线程生命周期进行全面的介绍。
Java线程的状态可以从java.lang.Thread的内部枚举类java.lang.Thread$State得知:
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过 新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked、WATING、TIMED_WATING)和死亡(Dead)5种状态。尤其是当线程启动以后,它不可能一直"霸占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是 线程状态也会多次在运行、阻塞之间切换。

新建状态(New)
API注释:
/**
* Thread state for a thread which has not yet started.
* 线程实例尚未启动时候的线程状态
*/
NEW,当线程对象创建后,即进入新建状态,如:
Thread t = new MyThread();就绪状态(Runnable)
API注释:
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE, 可运行状态下线程的线程状态。可运行状态下的线程在Java虚拟机中执行,但它可能执行等待操作系统的其他资源,例如处理器。当调用线程对象的
start()方法时,线程即进入就绪状态。处于就绪状态的线程只是说明此线程已经做好准备,随时等待CPU调度执行,并不是说执行了start()方法就立即执行。当Java线程实例调用了
Thread#start()之后,就会进入RUNNABLE状态。RUNNABLE状态可以认为包含两个子状态:READY和RUNNING。READY:该状态的线程可以被线程调度器进行调度使之更变为RUNNING状态。RUNNING:该状态表示线程正在运行,线程对象的run()方法中的代码所对应的的指令正在被CPU执行。- 当Java线程实例
Thread#yield()方法被调用时或者由于线程调度器的调度,线程实例的状态有可能由RUNNING转变为READY,但是从线程状态Thread#getState()获取到的状态依然是RUNNABLE。例如: public class ThreadState1 { public static void main(String[] args) throws Exception {
Thread thread = new Thread(()-> {
while (true){
Thread.yield();
}
});
thread.start();
Thread.sleep(2000);
System.out.println(thread.getState());
}
}
// 输出结果
RUNNABLE
运行状态(Running)
当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。
- WATING状态
WAITING是无限期的等待状态,这种状态下的线程不会被分配CPU执行时间。当一个线程执行了某些方法之后就会进入无限期等待状态,直到被显式唤醒,被唤醒后,线程状态由WAITING更变为RUNNABLE然后继续执行。

- TIMED WATING状态
TIMED WAITING就是有限期等待状态,它和WAITING有点相似,这种状态下的线程不会被分配CPU执行时间,不过这种状态下的线程不需要被显式唤醒,只需要等待超时限期到达就会被VM唤醒,有点类似于现实生活中的闹钟。

- 阻塞状态(Blocked)
处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。
阻塞状态分类
- 等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
- 同步阻塞:线程在获取
synchronized同步锁失败(因为锁被其它线程占用),它会进入到同步阻塞状态;- 其他阻塞:通过调用线程的sleep()或join()或发出I/O请求时,线程会进入到阻塞状态。当
sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态
线程执行完毕或者是异常退出,该线程结束生命周期。
线程相关方法
public class Thread{
// 线程的启动
public void start();
// 线程体
public void run();
// 已废弃
public void stop();
// 已废弃
public void resume();
// 已废弃
public void suspend();
// 在指定的毫秒数内让当前正在执行的线程休眠
public static void sleep(long millis);
// 同上,增加了纳秒参数
public static void sleep(long millis, int nanos);
// 测试线程是否处于活动状态
public boolean isAlive();
// 中断线程 - 进入阻塞状态
public void interrupt();
// 测试线程是否已经中断
public boolean isInterrupted();
// 测试当前线程是否已经中断
public static boolean interrupted();
// 等待该线程终止
public void join() throws InterruptedException;
// 等待该线程终止的时间最长为 millis 毫秒
public void join(long millis) throws InterruptedException;
// 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒
public void join(long millis, int nanos) throws InterruptedException;
}
笔者的微信公众号,每天一篇好文章:
java并发编程-线程生命周期的更多相关文章
- java并发编程基础—生命周期与线程控制
一.线程生命周期 线程被创建启动以后,他既不是一启动就进入执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(Running).阻塞(Bloc ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- java并发编程 线程基础
java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...
- java并发编程 | 线程详解
个人网站:https://chenmingyu.top/concurrent-thread/ 进程与线程 进程:操作系统在运行一个程序的时候就会为其创建一个进程(比如一个java程序),进程是资源分配 ...
- Java并发编程:线程间通信wait、notify
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程:线程和进程的创建(转)
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- Java并发编程——线程的基本概念和创建
一.线程的基本概念: 1.什么是进程.什么是是线程.多线程? 进程:一个正在运行的程序(程序进入内存运行就变成了一个进程).比如QQ程序就是一个进程. 线程:线程是进程中的一个执行单元,负责当前进程中 ...
- Java并发编程——线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...
- Java并发编程——线程池
本文的目录大纲: 一.Java中的ThreadPoolExecutor类 二.深入剖析线程池实现原理 三.使用示例 四.如何合理配置线程池的大小 一.Java中的ThreadPoolExecutor类 ...
随机推荐
- 二刷Redux笔记
关于react的一些思考 所有的数据全部先要发送给容器,然后容器负责接受数据单后再分发数据给他下面的组件,通过props来传递,一个页面就可以相当于一个容器,容器之中就会有很多子组件,一般组件只负责接 ...
- [256个管理学理论]003.鳄鱼法则(Alligator Principle)
鳄鱼法则(Alligator Principle) 来自于大洋彼岸的让你看不懂的解释: 这是经济学交易技术法则之一,也叫“鳄鱼效应”,它的意思是:假定一只鳄鱼咬住你的脚,如果你用手去试图挣脱你的脚,鳄 ...
- (五)Ajax修改购物车单品数量
需要gson-2.2.4.jar BookServlet.java package com.aff.bookstore.servlet; import java.io.IOException; imp ...
- Linux以指定用户非root用户运行程序、进程
方式一: 使用su命令切换用户运行 su 用户名 方式二: useradd -s /sbin/nologin -M test -s /sbin/nologin表示创建一个禁止登陆的用户(比如www ...
- 通过一个vue+elementUI的小实例来讲解一下它们是如何使用的
需求:点击一个按钮,弹出一个模态框,这个模态框有两个tab,tab中是各种报警条件,这些报警条件是从数据库中动态取出的,数据库中数据变更后,这个界面也要变更,我们可以查看和编辑这些报警条件.底部“确定 ...
- Chisel3 - util - LFSR16
https://mp.weixin.qq.com/s/DSdb4tmRwDTOki7mbyuu9A 实现16位线性反馈移位寄存器.可用于生成简单的伪随机数. 参 ...
- Spring ( 四 )Spring的AOP动态代理、切面编程
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.AOP切面编程 1.什么是AOP AOP是面向切面编程.全称:Aspect Oriented Pro ...
- 第九届蓝桥杯JavaC组决(国)赛真题
1:年龄问题 s夫人一向很神秘.这会儿有人问起她的年龄,她想了想说: "20年前,我丈夫的年龄刚好是我的2倍,而现在他的年龄刚好是我的1.5倍". 你能算出s夫人现在的年龄吗? 这 ...
- Java实现 LeetCode 328 奇偶链表
328. 奇偶链表 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起.请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性. 请尝试使用原地算法完成.你的算法的空间复杂 ...
- Java实现 蓝桥杯 素因子去重
素因子去重 问题描述 给定一个正整数n,求一个正整数p,满足p仅包含n的所有素因子,且每个素因子的次数不大于1 输入格式 一个整数,表示n 输出格式 输出一行,包含一个整数p. 样例输入 1000 样 ...