在我们开始本文话题时,我们不妨复习以下(或者说学习一下)操作系统的生命周期。
1.初始状态,这时候仅仅是语言层面上的线程创建,在操作系统中并没有创建这样一个线程:
2.当进入可运行状态时,说明该线程允许已被创建且一切准备就绪,随时可以进入运行状态了。
3.运行状态则以为着当前线程已分配到cpu时间片,执行自己所需要完成的工作了。
4.休眠状态,说明该线程正处于一个调用某个阻塞api或者等待某个事件完成的情况,这时候他就会适当cpu的使用权,进入休眠状态,直到等待事件出现后线程才会处于可运行状态。
5.终止状态:当线程完成了所有工作或者出现异常,那么线程最终就会走向人生的终点。
复制代码
好了,讲完操作系统的线程状态,我们基于java源码看看java的线程状态吧,这里注释已经写的很清楚了,所以笔者不需要过多赘述了
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;
}
复制代码
那么归纳一下,我们就可以看出java多线程虽然是6个状态,实际上翻译翻译就是操作系统拿到四种状态,如下图所示
可以看出笔者的归纳方式很简单,线程的初始状态和java线程的new一样的不多说,而操作系统的可运行和运行心态则是对应java的RUNNABLE是为什么呢?
我们从上面state源码注释就了解到,RUNNABLE状态即该线程已经在jvm中运行,但可能还在等待其他资源操作它,例如处理器。这句话的意思也很明显,我们可以用《java并发编程的实战》的一句话进行解释
在jvm层面看来,操作系统等待cpu使用权(可运行状态)以及等IO(休眠状态)都是属于等待某个资源操作,所以都归入RUNNABLE。
复制代码
对于操作系统对应休眠状态,由于jvm层面导致线程休眠的方式很多,所以在状态上也比操作系统多,下面我们就可以通过一张图来解释,为什么jvm层面会有这么多的休眠状态。
相信你们已经看完了这张图,那么我们就用几个示例来演示线程状态的切换
首先是new状态
/**
* 线程的new状态场景
*/
public static void newState() {
Thread thread = new Thread(() -> {
});
System.out.println(thread.getState());
}
复制代码
RUNNABLE与BLOCKED状态转换
/**
* 线程出现block的场景
*
* @throws Exception
*/
public static void blockState() throws Exception {
Thread t1 = new Thread(new BlockThread());
Thread t2 = new Thread(new BlockThread());
t1.start();
//当t2等待t1释放synchronized内置锁时就会处于block状态
t2.start();
Thread.sleep(1000);
System.out.println(t2.getState());
System.exit(0);
}
复制代码
public class BlockThread implements Runnable {
@Override
public void run() {
loop();
}
/**
* 拿着synchronized内置锁死循环
*/
public static synchronized void loop() {
while (true) {
}
}
}
复制代码
RUNNABLE与WAITING状态转换,根据上图说明调用join即可进入waiting
public static void waitingState() throws Exception {
Thread t1 = Thread.currentThread();
Thread t2 = new Thread(() -> {
try {
// 主线程休眠
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("线程休眠失败,失败原因 " + e);
}
// t2运行 那么t1就得等着
System.out.println(t1.getState());
});
t2.start();
t2.join();
}
复制代码
调⽤了 sleep(long) 等⽅法,线程从 RUNNABLE 变为 TIMED-WAITING 状态
public static void timeWaitingState()throws Exception{
Thread t=new Thread(()->{
try {
//让主线程进入等待状态,自己也得等着主线程睡完
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("线程休眠失败,失败原因 " + e);
}
});
t.start();
Thread.sleep(1000);
System.out.println(t.getState());
}
复制代码
线程执⾏完⾃然就到了 TERMINATED 状态了
public static void terminatedState()throws Exception{
Thread thread=new Thread(()->{});
thread.start();
//子线程直接执行完 进入terminated
Thread.sleep(1000);
System.out.println(thread.getState());
}
复制代码




近期评论