@

线程状态 Thread.State

状态类型

在指定的时间点, 一个线程有且只有一种状态。 这些状态是 JVM 的状态, 他们并没有反映操作系统的状态。

定义

Thread 的状态是定义在 Thread 内部的枚举类型。

public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}

在定义中, 我们知道共有 6 种类型。

说明

状态 说明
NEW 至今尚未启动的线程处于这种状态
RUNNABLE 正在 Java 虚拟机中执行的线程处于这种状态。 因为可能在等待其他的资源, 比如处理器。
BLOCKED 受阻塞并等待某个监视器锁的线程处于这种状态
WAITING 无限期地等待另一个线程来执行。某一特定操作的线程处于这种状态
TIMED_WAITING 等待另一个线程来执行。取决于指定等待时间的操作的线程处于这种状态
TERMINATED 已退出的线程处于这种状态

状态转换

借用 《Java 并发编程的艺术》图一张

从以上的图可以看出,

  1. 线程创建后未启动未 「NEW」 状态, 通过 start() 函数转换为 「RUNNABLE」状态。
  2. 「RUNNABLE」 状态通过各函数, 可以与「WAITING」、「TIMED-WAITING」、「BLOCKED」 进行双向切换。
  3. 「RUNNABLE」 状态在线程结束后转换为 「TERMINATED」 状态。

也就是说, 全部的状态是以 「RUNNABLE」 为中心的。

状态验证

「NEW」-> 「RUNNABLE」 -> 「TERMINATED」

创建一个实现 Runnable 的类

public class StateTestThread implements Runnable{
public StateTestThread() {
// 此时的线程还是 main
System.out.println(Thread.currentThread().getName()+" state in Constructor:"+
Thread.currentThread().getState());
} public void run() {
System.out.println(Thread.currentThread().getName()+" state in Run:"+
Thread.currentThread().getState());
}
}

创建一个测试类

public class ThreadStateTest {

    public static void main(String[] args) {
StateTestThread stateTestThread = new StateTestThread();
Thread thread = new Thread(stateTestThread);
System.out.println(thread.getName()+" state after constructor:"
+thread.getState());
try {
Thread.sleep(1000L);
thread.start();
Thread.sleep(1000L);
System.out.println(thread.getName()+" state after run:"
+thread.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

运行结果

「RUNNABLE」 -> 「TIMED_WAITING」

public class ThreadStateTest {

    public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
public void run() {
long begin = System.currentTimeMillis();
for (int i = 0; i < (1 << 25); i++) {
int j = (int) Math.sqrt(i);
// 该条件永远不成立, 只是为了计算
if (j * j > i) {
break;
}
}
long end = System.currentTimeMillis();
System.out.println("calculate end:"+(end - begin));
try {
System.out.println("begin sleep");
Thread.sleep(5000L);
System.out.println("end sleep");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
try {
thread.start();
Thread.sleep(100L);
System.out.println(thread.getName()+" state :"
+thread.getState());
Thread.sleep(1000L);
System.out.println(thread.getName()+" state :"
+thread.getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

结果如下:

Thread-0 的状态从 「RUNNABLE」 转化为 「TIMED_WAITING」

「RUNNABLE」 -> 「WAITING」

public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
final Object lock = new Object();
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) { }
}
}
}); thread.start();
System.out.println(thread.getName()+" state :"
+thread.getState());
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread.getName()+" state :"
+thread.getState());
}

运行结果

「RUNNABLE」 -> 「BLOCKED」

先创建一个 Runnable 子类

public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
final Object lock = new Object();
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) { }
}
}
}); thread.start();
System.out.println(thread.getName()+" state :"+thread.getState());
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread.getName()+" state :"+thread.getState());
}

测试方法

public static void main(String[] args) {
BlockedStateRun blockedStateRun = new BlockedStateRun();
Thread thread1= new Thread(blockedStateRun);
Thread thread2= new Thread(blockedStateRun);
thread1.setName("First");
thread1.start();
thread2.setName("Second");
thread2.start();
try {
Thread.sleep(200L);
System.out.println(thread1.getName()+"::"+thread1.getState());
System.out.println(thread2.getName()+"::"+thread2.getState());
} catch (InterruptedException e) {
e.printStackTrace();
} }

最后的运行结果:

Java 多线程(三)之线程状态及其验证的更多相关文章

  1. Java 多线程创建和线程状态

    一.进程和线程 多任务操作系统中,每个运行的任务是操作系统运行的独立程序. 为什么引进进程的概念? 为了使得程序能并发执行,并对并发执行的程序加以描述和控制. 因为通常的程序不能并发执行,为使程序(含 ...

  2. java多线程三之线程协作与通信实例

    多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition. ...

  3. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  4. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  5. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  6. Java多线程——进程和线程

    Java多线程——进程和线程 摘要:本文主要解释在Java这门编程语言中,什么是进程,什么是线程,以及二者之间的关系. 部分内容来自以下博客: https://www.cnblogs.com/dolp ...

  7. Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗

    在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...

  8. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  9. Java多线程系列--“JUC线程池”05之 线程池原理(四)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  10. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

随机推荐

  1. 一次失败的生产系统中AlwaysOn AG切换经历

    14:25分左右,某数据库主副本服务器崩溃报错,在数据库无法接收SQL语句进行调整的情况下重启了主副本服务器. 由于服务器重启时间会比较长,为了保证主副本服务器重启期间数据库能正常进行写入,强制将主库 ...

  2. web导出excel文件的几种方法

    总的来说,两种方法:服务器端生成和浏览器端生成. 服务器端生成就是:根据用户请求,获取相应的数据,使用poi/jxl, jacob/jawin+excel,或是用数据拼html的table或是cvs纯 ...

  3. angular、jquery、vue 的区别与联系

    angular和jquery的区别 angular中是尽量避免操作DOM, angular是基于数据驱动, 适合做数据操作比较繁琐的项目,angular适用于单页面开发,是一个比较完善的mvvm框架, ...

  4. 【转】Java学习---深入理解线程池

    [原文]https://www.toutiao.com/i6566022142666736131/ 我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很 ...

  5. 【转】电脑运行命令CMD集锦

    在win7系统里直接点开始,最左下面有个搜索框,在里面直接输CMD,回车就可以:或者win键+R键,出现对话框,输入CMD,回车就可以了: winver 检查Windows版本 wmimgmt.msc ...

  6. mysql用户管理与权限

    1.设置密码 set password for 用户名@localhost = password('密码'); 2.取消密码 set password for 用户名@localhost = pass ...

  7. 团队作业——Alpha冲刺 11/12

    团队作业--Alpha冲刺 冲刺任务安排 杨光海天 今日任务:预览界面布局实现,并留下交互接口 明日任务:预览界面中自定义保存的实现 郭剑南 今日任务:尝试解决Python编写程序无法在Android ...

  8. Django商城项目笔记No.11用户部分-QQ登录1获取QQ登录网址

    Django商城项目笔记No.11用户部分-QQ登录 QQ登录,亦即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 若想实现QQ登录,需要成为QQ互联 ...

  9. Maven 安装源码和文档到本地仓库

    一: 1:   mvn source:jar 生成源码的jar包 2: mvn source:jar install 将源码安装到本地仓库 ,可以直接mvn source:jar install 一部 ...

  10. Node.js实战(九)之事件循环

    Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高. Node.js 几乎每一个 API 都是支持回调函数的. Node ...