线程的状态

Thread.State枚举类型中定义了线程的六种状态:NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED

线程在某一时刻只能拥有一种状态,但是在线程的整个生命周期,线程的状态会发生变化。

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

各状态的说明

NEW

NEW状态是线程已经被创建,但还没调用start()。此时的线程是不可运行的,CPU将不会为其分配时间。

RUNNABLE

当新创建的线程调用了start(),线程便进入了RUNNABLE状态。

RUNNABLE状态是指可以获得CPU运行时间的状态,如果线程在此状态下,线程有两种子状态,一种是等待CPU时间,另一种是获得了CPU时间在执行代码。

BLOCKED

BLOCKED状态是线程无法获取对象锁时的状态。此状态下线程会阻塞,当线程成功获取到锁,线程将切换为RUNNABLE状态。

BLOCKED状态无法获得CPU运行时间。

WAITING

WAITING状态是指是指线程在执行过程中,主动出让自己CPU运行时间,让其他线程先执行,自己等待其它线程的特定操作后再恢复执行。

TIMED_WAITING

TIMED_WAITINGWAITING状态相似,TIMED_WAITING增加了时间限制,其实没有外部信号,在等待时间超时后,线程也会恢复。

TERMINATED

TERMINATED是线程的终止态,当线程执行完自己的任务,或在执行任务中发生了异常,线程都会进入TERMINATED,表示线程已经到了生命周期的末尾。

下图是关于线程间各状态切换的过程及发生状态切换的一些条件。

操作 操作前线程状态 操作后线程状态 是否出让CPU时间 是否需要先持有对象锁 是否释放对象锁
new Thread() NEW
Thread.start() NEW RUNNABLE
synchronized能得到对象锁 RUNNABLE RUNNABLE
synchronized无法得到对象锁 RUNNABLE BLOCKED
Thread.join() RUNNABLE WAITING
Thread.join(t) RUNNABLE TIMED_WAITING
Thread.sleep(t) RUNNABLE TIMED_WAITING
Object.wait() RUNNABLE WAITING
Object.wait(t) RUNNABLE TIMED_WAITING
Object.notify() / Object.notifyAll() RUNNABLE RUNNABLE
Lock.lock() RUNNABLE WAITING
Lock.tryLock(t) RUNNABLE TIMED_WAITING
LockSupport.park() RUNNABLE WAITING
LockSupport.parkNanos(t)/LockSupport.parkUntil(t) RUNNABLE TIMED_WAITING
执行结束/执行异常 RUNNABLE TERMINATED

以下是一些测试代码,可以运行下清晰的了解到状态。

各状态切换测试:

public class ThreadStateTest {

    public static void main(String[] args){
threadStateNew(); workingThread(); threadStateTerminate(); threadBlockedByLock(); threadBlockedBySynchronized(); threadSleep(); threadWait(); threadTimedWait();
} private static void threadStateNew(){
System.out.println("--------------------------");
System.out.print("Never Start Thread State:");
Thread thread = new Thread(()->{ }, "Thread Never Start");
//print NEW
System.out.println(thread.getState());
System.out.println("--------------------------");
} private static void workingThread(){
System.out.println("--------------------------");
Thread thread = new Thread(()->{
for(int i=0; i<100; i++){
doSomeElse();
}
}); thread.start(); doSomeElse();
//print RUNNABLE
System.out.println("Working Thread State:" + thread.getState());
System.out.println("--------------------------");
} private static void threadStateTerminate(){
System.out.println("--------------------------");
System.out.print("Finish Job Thread State:");
Thread thread = new Thread(()->{ }, "Thread Finish Job");
thread.start(); try {
//Main Thread Will Wait util this thread finished job
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//print TERMINATED
System.out.println(thread.getState());
System.out.println("--------------------------");
} private static void threadBlockedByLock(){
System.out.println("--------------------------");
System.out.print("Thread State Blocked By Lock:");
ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread(()->{
lock.lock();
}, "Blocked Thread"); lock.lock(); thread.start(); doSomeElse();
//print WAITING
System.out.println(thread.getState()); lock.unlock();
System.out.println("--------------------------");
} private static void threadBlockedBySynchronized(){
System.out.println("--------------------------");
System.out.print("Thread Blocked By Synchronized:");
Thread thread = new Thread(()->{
synchronized (ThreadStateTest.class){ }
}, "Blocked by Synchronized Thread"); synchronized (ThreadStateTest.class){
thread.start();
doSomeElse();
//print BLOCKED
System.out.println(thread.getState());
}
System.out.println("--------------------------");
} private static void threadSleep(){
System.out.println("--------------------------");
System.out.print("Sleeping Thread:");
Thread thread = new Thread(()->{
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thread sleep"); thread.start();
doSomeElse();
//print TIMED_WAITING
System.out.println(thread.getState());
System.out.println("--------------------------");
} private static void threadWait(){
System.out.println("--------------------------");
System.out.print("Thread Waiting:");
Object lock = new Object();
Thread threadA = new Thread(()->{
synchronized (lock){
try {
lock.wait(); for(int i=0; i<100; i++){
doSomeElse();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }, "Thread Waiting"); Thread threadB = new Thread(()->{
synchronized (lock){
//print WAITING
System.out.println("Before Notify, Thread A State:" + threadA.getState());
lock.notify();
//print BLOCKED
System.out.println("After Notify, Thread A State:" + threadA.getState());
}
}); threadA.start();
doSomeElse();
threadB.start(); try {
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//print RUNNABLE
System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
System.out.println("--------------------------");
} private static void threadTimedWait(){
System.out.println("--------------------------");
System.out.print("Thread Waiting:");
Object lock = new Object();
Thread threadA = new Thread(()->{
synchronized (lock){
try {
lock.wait(1000); for(int i=0; i<100; i++){
doSomeElse();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }, "Thread Waiting"); Thread threadB = new Thread(()->{
synchronized (lock){
//print TIMED_WAITING
System.out.println("Before Notify, Thread A State:" + threadA.getState());
lock.notify();
//print BLOCKED
System.out.println("After Notify, Thread A State:" + threadA.getState());
}
}); threadA.start();
doSomeElse();
threadB.start(); try {
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//print RUNNABLE
System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
System.out.println("--------------------------");
}
/**
* take some times, let the thread get cpu time
*/
private static void doSomeElse(){
double meanless = 0d;
for(int i=0; i<10000; i++){
meanless += Math.random();
}
} }

CPU时间运行测试:

public class ThreadCPUTimeTest {

    public static void main(String[] args) {
testBlockedThreadCPUTime();
} protected static void testBlockedThreadCPUTime() {
Object lock = new Object(); Thread threadA = new Thread(() -> {
synchronized (lock) {
doSomethingElse();
}
}, "ThreadA: Blocked because of synchronized"); Thread threadB = new Thread(() -> {
synchronized (lock) {
try {
threadA.start();
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "ThreadB: With Monitor But Sleep"); threadB.start();
//Main Thread Executing Job
for (int i = 0; i < 100000; i++) {
doSomethingElse();
}
} private static void doSomethingElse() {
double meanless = 0d; for (int i = 0; i < 10000; i++) {
meanless += Math.random();
}
}
}

用VISUALVM可以统计CPU时间:

详细代码可以GitHub

线程状态及各状态下与锁和CPU的关系的更多相关文章

  1. java 线程的几种状态

    java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...

  2. 在java中怎样实现多线程?线程的4种状态

    一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 ...

  3. Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)

    线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...

  4. 透彻讲解,Java线程的6种状态及切换

    Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法.2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...

  5. Java线程的5种状态及切换(透彻讲解)-京东面试

    一.Thread的几个重要方法: 我们先了解一下Thread的几个重要方法. a.start()方法,开始执行该线程:b.stop()方法,强制结束该线程执行:c.join方法,等待该线程结束.d.s ...

  6. 【转】java 线程的几种状态

    java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...

  7. 线程的几种状态转换<转>

    线程在一定条件下,状态会发生变化.线程一共有以下几种状态: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法. ...

  8. Java 多线程 线程的五种状态,线程 Sleep, Wait, notify, notifyAll

    一.先来看看Thread类里面都有哪几种状态,在Thread.class中可以找到这个枚举,它定义了线程的相关状态: public enum State { NEW, RUNNABLE, BLOCKE ...

  9. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

随机推荐

  1. PTA 7-42 整型关键字的散列映射(手写哈希表的线性探测法)

    本题考点: 整型哈希表的线性探测法 给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射到长度为P的散列表中.用线性探测法解决冲突. 输入格式: 输入第一行首先给出两个正整数N(≤10 ...

  2. Golang入门(3):一天学完GO的进阶语法

    摘要 在上一篇文章中,我们聊了聊Golang中的一些基础的语法,如变量的定义.条件语句.循环语句等等.他们和其他语言很相似,我们只需要看一看它们之间的区别,就差不多可以掌握了,所以作者称它们为&quo ...

  3. 【php】面向对象(五)

    一. 类型约束: a) 约束函数可传入的参数类型二. 类的遍历 a) Foreach b) 可以将类当中的所有成员属性遍历出来三. 关于操作类与对象的一些函数: a) 判断函数 i. Function ...

  4. Java第五天,API常用类,静态(static)、集合(ArrayList)、日期(Date)、日历(Calendar)的使用方法

    上文中我们学习到了Random随机数类和ArrayList<E>集合.这两个知识点都是经常用到的,那么除了这两个外,还有哪些知识点是我们所必须掌握的呢? static 使用static需要 ...

  5. Array(数组)对象-->lastIndexOf() 方法

    1.定义和用法 lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置,如果指定第二个参数 start,则在一个字符串中的指定位置从后向前搜索. 语法: string.lastInde ...

  6. 虚拟机安装windows sever2008

    1.打开并进行新建虚拟机 2.默认选择“典型” 3.选择“安装程序盘映像文件”,并‘浏览’选择本地的文件 4. 5.后面的默认选择即可,安装路径可自己修改 6.这一步的磁盘大小可自己修改的,这里先预设 ...

  7. Windows Server 2016 Storage Replication

    Storage Replication是Windows Server 2016中新增的一项功能,它是利用windows server自带的块存储复制技术 首先,我们简答粗暴的交代一下部署需求: 1.该 ...

  8. Java成长第四集--文本处理IO流

    Java IO流在实际业务中使用的频率还是蛮高的,一些业务场景比如,文件的上传和导出,文件的读取等基本都是通过操作IO流来实现的,所以IO流是我们现在学习过程中必须要掌握的技能之一,熟练的使用IO流, ...

  9. Activity A 跳转到Activity B 生命周期

    又被生命周期折磨了一段时间,这次是被onPause 和 onStop 折磨了,一直认为Activity A 跳转到到 Activity B的生命周期是onPause(A),onStop(A),onCr ...

  10. Nexus3 集成 crowd 插件

    公司使用的软件开发和协作工具为 Atlassian 系列软件,所以统一使用 crowd 来实现统一登录(SSO). crowd 配置 具体操作细节见我之前写的 Atlassian 系列软件安装(Cro ...