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. 进程 是一个正在执行的程序.是程序在计算机上的一次运行活动. 每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 系统以进程为基本单位进行系统资源的调度 ...
随机推荐
- 【POJ 1155】TELE
[题目链接] 点击打开链接 [算法] 树形DP f[i][j]表示以i为根的子树中,选了j个叶子节点,所能带来的最大收益 不难发现这就是一个经典的背包问题,不过是在树上做背包罢了 最后,判断f[1][ ...
- Bootstrap指定表格字段宽度
默认情况下,表格会占据屏幕所有宽度,可以使用bootstrap的布局功能.但表格标题字段的宽度必须与相应字段内容的宽度一致. <div class="container"&g ...
- bzoj 1951: [Sdoi2010]古代猪文 【中国剩余定理+欧拉定理+组合数学+卢卡斯定理】
首先化简,题目要求的是 \[ G^{\sum_{i|n}C_{n}^{i}}\%p \] 对于乘方形式快速幂就行了,因为p是质数,所以可以用欧拉定理 \[ G^{\sum_{i|n}C_{n}^{i} ...
- python删除列表中元素的方法
删除列表中元素的三种方法-remove.pop.del 1 1.remove: 删除单个元素,删除首个符合条件的元素,按值删除 2 举例说明: 3 >>> str=[1,2,3,4, ...
- 窗口Dialog
Dialog是窗口的意思,它是Window的子类.与frame相比,frame是我们大的窗口,而dialog便是那种弹出来和你说话的对话框. Dialog类的默认布局是BorderLayout Dia ...
- VGG16 pre-trained model 实现 image classification
站在巨人的肩膀上!使用VGG预先训练好的weight来,进行自己的分类. 下一阶段是在这上面进行自己的修改,完成自己想要的功能. Github源码 Github上有我全部的工程代码. 环境配置 Pyt ...
- DEV—【GridControl 按钮列无法触发点击事件解决方案】
需要在按钮列的OptionColumn属性栏中找到下面两个属性,并且改为True AllowEdit=True,AllowFocus=True.
- 用C#操作word替换字符,用spire
这两天想写个小程序,是用C#操作word文档的.许多人都对微软本身的解决方案COM组件十分不看好,比如需要本机安装office等等,总之吐槽很多,直接放弃. 搜到一个国产的npoi库,据说操作简单功能 ...
- 构建一个.net的干货类库,以便于快速的开发 - 验证码
一个验证码对于一个网站的作用不言而喻,而随着技术的发展验证码的种类也开始多了起来,发展至今很多网站已经不再使用一种验证码,为满足需求程序猿就要写很多的方法来适应需求,今天我就来介绍我之前收集到的验证码 ...
- SpringMVC与请求控制器
MVC设计模式 视图(View) -对应组件:JSP或者HTML文件 控制器(controller) -对应组件:Servlet 模型(Model) -对应组件:JavaBean MVC ...