B3. Cocurrent 线程的状态
【概述】
1). java.lang.Thread 类中定义了一个枚举 State, 定义了线程的六种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW, /**
* 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, /**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED, /**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING, /**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING, /**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
2). 通过 getState() 方法可以获取当前线程的状态
public State getState() {
// get current thread state
return sun.misc.VM.toThreadState(threadStatus);
}
【详细描述】
- NEW(新建状态): 线程对象被创建,还没有调用 start() 方法启动线程。
- RUNNABLE(可运行状态):线程处于可运行状态,可能处于运行中,也可能在像进程一样在等待其他资源,例如 CPU 的调用。
BLOCKED(阻塞状态):线程被阻塞等待一个对象的监控锁(monitor lock),以进入同步代码块或同步方法或者重新进入同步代码块或者同步方法。
重入的情况例如:在同步代码块或同步方法中调用 Object.wait 方法后进入等待状态(WAITING), 被唤醒(Object.notify 或 Object.notifyAll)后进入阻塞状态(BLOCKED),需要重新获得对象的监控锁(monitor lock),然后才执行 Object.wait 后面的代码。
- WAITING(等待状态):线程可能因为执行了以下方法而进入等待状态
1). Object#wait(),没有超时设置
2). Thread#join(),没有超时设置
3). LockSupport#park()
一个进入WAITING(等待状态)的线程,需要另外的线程执行特别的动作才能将其唤醒:
1). 一个线程执行了 Object.wait 进入等待状态,则需要另外的线程执行 Object.notify 或 Object.notifyAll 将其唤醒,注意 Object.notify 只会唤醒其中一个等待的线程,具体唤醒哪个是不确定的。
2). 一个线程调用了另外一个线程的 join 方法,等需要等待另外一个线程运行结束,即处于TERMINATED(终止状态),才会被唤醒。
3). 一个线程使用 LockSupport.park 进入等待状态,则另外的线程可以执行 LockSupport.unpark 将其唤醒。
TIMED_WAITING(有时间限制的等待状态):线程处于该状态会等待特定时间后被唤醒。线程可能因为执行了以下方法而进入有时间限制的等待状态:
1). Object#wait(long timeout): 参数为毫秒
2). Thread#join(long millis)
3). Thread#sleep(long millis)
4). LockSupport#parkNanos(long nanos)
5). LockSupport#parkUntil(long deadline)TERMINATED(终止状态):线程处于终止状态存在两种可能:
1). 线程执行完 run() 方法
2). 执行 run() 方法过程中抛出异常
【测试代码】
/**
1. 创建线程对象
NEW(新建状态):线程对象被创建,还没有调用 start() 方法启动线程 2. 启动线程:调用 start() 方法
RUNNABLE(可运行状态):线程正在等待 CPU 的调用
主线程暂停 100 ms, 让测试线程开始执行
RUNNABLE(可运行状态):线程开始执行 3.主线程先获得 obj 的监控锁(monitor lock), 测试线程进入阻塞状态
BLOCKED(阻塞状态):obj 的监控锁(monitor lock)被 主线程持有, 故测试线程进入阻塞状态, 等待获取 obj 的监控锁 (monitor lock)
RUNNABLE(可运行状态):测试线程获得 obj 的监控锁(monitor lock), 执行同步代码块代码 4.测试线程调用 Object#wait() 进入等待状态, 释放 obj 的监控锁(monitor lock)
WAITING(等待状态):测试线程需要被唤醒
主线程获得obj 的监控锁(monitor lock), 主线程调用 Object#notifyAll 唤醒等待线程
BLOCKED(阻塞状态):obj 的监控锁(monitor lock)被 main线程持有, 故测试线程进入阻塞状态, 等待获取 obj 的监控锁 (monitor lock)
RUNNABLE(可运行状态):测试线程被唤醒, 并重新获得 obj 的监控锁(monitor lock) 5.主线程暂停 100ms, 测试线程暂停 500 ms, 此时测试线程进入有时间限制的等待状态
TIMED_WAITING(有时间限制的等待状态):线程在特定时间的等待后会被唤醒 6.主线程暂停 1000 ms, 等待测试线程执行完成
TERMINATED(终止状态):线程已经执行完成
*/
public class Main { public static void main(String[] args) throws InterruptedException {
//1. 创建线程对象
System.out.println("1. 创建线程对象");
MyThread t = new MyThread();
System.out.println(t.getState() + "(新建状态):线程对象被创建,还没有调用 start() 方法启动线程"); //2. 启动线程:调用 start() 方法
System.out.println("\n2. 启动线程:调用 start() 方法");
t.start();
System.out.println(t.getState() + "(可运行状态):线程正在等待 CPU 的调用"); //3. 主线程抢先获得 obj 的监控锁 (monitor lock);
synchronized (t.obj) {
System.out.println("主线程暂停 100 ms, 让测试线程开始执行");
Thread.sleep(100); System.out.println("\n3.主线程先获得 obj 的监控锁(monitor lock), 测试线程进入阻塞状态");
System.out.println(t.getState() + "(阻塞状态):obj 的监控锁(monitor lock)被 main线程持有, 故测试线程进入阻塞状态, 等待获取 obj 的监控锁 (monitor lock)");
} //4.测试线程调用 Object#wait() 进入等待状态, 释放 obj 的监控锁(monitor lock)
Thread.sleep(100);//主线程等待 100 ms. 让测试先获得 obj 的监控锁 (monitor lock)
System.out.println(t.getState() + "(等待状态):测试线程需要被唤醒");
synchronized (t.obj) {
System.out.println("主线程获得obj 的监控锁(monitor lock), 调用 Object#notifyAll 唤醒等待线程");
t.obj.notifyAll(); //如果没有唤醒, 测试线程会一直处于等待状态
System.out.println(t.getState() + "(阻塞状态):obj 的监控锁(monitor lock)被 主线程持有, 故测试线程进入阻塞状态, 等待获取 obj 的监控锁 (monitor lock)");
} //5.主线程暂停 100ms, 测试线程暂停 500 ms, 此时测试线程进入有时间限制的等待状态
Thread.sleep(100);
System.out.println(t.getState() + "(有时间限制的等待状态):线程在特定时间的等待后会被唤醒"); //6.主线程暂停 1000 ms, 等待测试线程执行完成
System.out.println("\n6.主线程暂停 1000 ms, 等待测试线程执行完成");
Thread.sleep(1000);
System.out.println(t.getState() + "(终止状态):线程已经执行完成");
}
} class MyThread extends Thread{ public Object obj = new Object(); @Override
public void run(){
//线程开始进行业务处理
System.out.println(getState() + "(可运行状态):线程开始执行");
try {
//使线程进入 WAITING (等待状态)
synchronized (obj) {
System.out.println(this.getState() + "(可运行状态):测试线程获得 obj 的监控锁(monitor lock), 执行同步代码块代码");
//4.测试线程调用 Object#wait() 进入等待状态, 释放 obj 的监控锁(monitor lock)
System.out.println("\n4.测试线程调用 Object#wait() 进入等待状态, 释放 obj 的监控锁(monitor lock)");
obj.wait();
System.out.println(this.getState() + "(可运行状态):测试线程被唤醒, 并重新获得 obj 的监控锁(monitor lock)");
}
//5.测试线程进入 TIMED_WAITING (有时间限制的等待状态)
System.out.println("\n5.主线程暂停 100ms, 测试线程暂停 500 ms, 此时测试线程进入有时间限制的等待状态");
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
B3. Cocurrent 线程的状态的更多相关文章
- java基础知识回顾之java Thread类学习(十)--线程的状态以及转化使用的方法介绍
线程的概述: 线程是程序的多个执行路径,执行调度的单位,依托于进程存在.线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间叫做线程栈,是建立线程的时候由系 ...
- java 22 - 18 多线程之 线程的状态转换、线程组
线程的状态转换图解:图片 线程的线程组: 线程组: 把多个线程组合到一起. 它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制. 首先创建一个Runnable的实现类 publi ...
- iOS开发多线程篇—线程的状态
iOS开发多线程篇—线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(te ...
- 【学习总结】【多线程】 安全隐患 & 通讯 & 线程的状态
一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数 ...
- Android(java)学习笔记72:线程的状态转换图以及常见执行情况
1. 线程的状态转换图以及常见执行情况: 2. 线程状态类型: (1)新建状态(New):新创建了一个线程对象.(2)就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start() ...
- Java 线程的状态
Java Thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
- OC中线程的状态相关
1.线程的状态NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; ...
- JAVA中线程的状态
java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW:至今尚未启动的线程的状态. RUNNABLE:可运行线程的线程状态. ...
- Java多线程(一) —— 线程的状态详解
一.多线程概述 1. 进程 是一个正在执行的程序.是程序在计算机上的一次运行活动. 每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 系统以进程为基本单位进行系统资源的调度 ...
随机推荐
- BZOJ:2819 NIM(树链剖分||DFS序 &&NIM博弈)
著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略的.于是v ...
- bzoj 3781 小B的询问 —— 莫队
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3781 就是莫队,左端点分块排序,块内按右端点排序,然后直接做即可. 代码如下: #inclu ...
- openpyxl操作excel
[转] openpyxl库可以读写xlsx格式的文件,对于xls旧格式的文件只能用xlrd读,xlwt写来完成了. python有很多模块都是用来操作excel的,比如xlrd,xlwt,pyExce ...
- eoj 3507 坑爹的售票机
EOJ 3507 坑爹的售票机 问题描述 oxx 和 xjj 决定和小伙伴们一同坐船前往 Xiamen.去 Xiamen 的船票一张 p 元. 当他们满怀兴致地来到港口时发现居然只有不设找零的自动 ...
- 使用 SQL Server Management Studio的活动和监视器 查看运行的SQL语句
使用SQL Server Management Studio可以查看SQL Server 服务器执行的SQL语句,支持sql server,(LocalDB)\V11.0,Projects\v12和s ...
- Oracle:ORA-12154: TNS:could not resolve the connect identifier specified
ORA-12154: TNS: 无法解析指定的连接标识符 注册表:regedit 安装oracle后用Net Manager 配置好服务名称之后,测试成功,可是PL/SQL无法连接 http://we ...
- bzoj 1863: [Zjoi2006]trouble 皇帝的烦恼【二分+dp】
二分答案,注意l是max(a[i]+a[i+1]),r是sum_a 判断的时候用dp,设f[i]为i与1最少的相同颜色数,g[i]为i与1最多的相同颜色数,转移是f[i]=max(a[i]-(w-a[ ...
- bzoj 1009: [HNOI2008]GT考试【kmp+dp+矩阵快速幂】
看n和k的范围长得就很像矩阵乘法了 设f[i][j]表示到第i个位置的后缀最长匹配目标串的j位.转移的话显然是枚举0~9,然后选择f[i+1]中能被他转移的加起来,需要用到next数组.然后构造矩阵的 ...
- java 学习书籍
<Effective java> <深入理解java虚拟机> <Java并发编程实践> <Java Performance> <java解惑> ...
- HDFS执行getDatanodeReport输出信息
HDFS执行getDatanodeReport输出信息: Name: (192.168.101.100) Hostname: bigsrv Decommission Status : Normal C ...