title: Java多线程_线程的生命周期与6种状态
tags: Java
date: 2022-03-02 10:20:14
Java多线程_线程的生命周期与6种状态
一、线程的生命周期
当线程被创建并启动之后,并不是一启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中要经过:新建(NEW)、运行(RUNNABLE)、阻塞(BLOCKED)、永久等待(WAITING)、超时等待(WIME_WAITING)、终止(TERMINATED)。
当线程被启动的时候,它并不可能一直独占CPU运行,所以CPU是一直在多条线程之间来回切换运行,于是线程也是不停在运行 与 就绪之间进行切换。
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;
}
二、线程的主要状态
1、新建状态(NEW):
实现Runnable接口和继承Thread可以得到一个线程类,使用new关键字创建了一个程序之后,改线程就处于新建状态,此时的线程和其他Java对象一样,仅仅由Java虚拟机为其分配内存,并初始化成员变量的值。
当线程对象调用了start()方法之后,该线程处于就绪状态,Java虚拟机为其创建方法调用栈和程序计数器,处于这个状态中的线程并没有开始运行,只是表示该线程可以运行了,至于何时开始取决于CPU调度器的调度。
**注意:**启动线程使用方法start(),而不是run()方法!永远不要直接调用线程对象的run()方法!当调用start()方法后,系统会将该对象的run()方法作为程序执行体来处理;如果直接调用对象的run()方法,系统会将线程对象当做一个普通对象,而run()方法也是一个普通方法,而不是线程执行体。
2、运行状态(RUNNABLE):
在线程的运行状态中也可分为两个小状态:运行中状态(Running)、就绪状态(Ready)。当处于就绪状态的线程获得了CPU,将会开始执行run()方法的线程执行体,则该线程处于运行中状态。
Ready(就绪状态): 等待调度器调度
Running(运行中状态): 被调度器(scheduler)选中,CPU正在执行
Ready ----> 调度器选中 ----> Running
Running ----> 调度器切换 | Thread.yeild() 方法—> Ready
3、永久等待状态(WAITING):
当调用wait()方法或join()方法此时的线程将退出运行状态,进入永久等待状态,除非使用notify()方法或notifyAll()方法主动唤醒,否则永久等待。
进入永久等待状态:
Runnable --> wait()方法 | join() 方法 ----> Waiting
退出永久等待状态:
Waiting -> notify()方法 | notifyAll() ----> Runnable
4、超时等待状态(TIMED_WAITING):
当调用sleep(long millis)、wait(long millis)、join(long millis)这三个方法时,线程将进入超时等待状态,等待设定时间long millis结束或使用notify()或notifyAll()对其主动唤醒退出超时等待状态,进入到运行就绪状态等待CPU调度分配资源。
进入超时等待状态:
Runnable --> sleep(long millis) | wait(long millis) | join(long millis) —> Timed_Waiting
超时等待状态:
Timed_Waiting --> 设置时间结束 | notify() | notifyAll() --> Runnable
5、阻塞状态(BLOCKED):
阻塞状态是被监视器锁监视的线程, 被同步锁或者IO锁阻塞 ,线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态 。为了线程的安全,使用synchronized关键字给线程上锁,使得多个线程能够有秩序的进入同步代码块获取权限。
进入阻塞状态:
Runnable —> 没有获取锁 ----> 阻塞
退出阻塞状态:
阻塞 —> 获取锁对象 —> Runnable
6、终止状态(TERMINATED):
线程终止状态也称为线程死亡,有三种方式进入该状态:
①run()或call()方法执行完成,线程正常结束。
②线程抛出一个未捕获的Exception或Error。
③直接调用该线程的stop()方法来结束该线程----该方法容易死锁,不建议使用。
Runnable ----> 任务方法执行完毕|发生异常 —> Terminated
线程对象的isAlive()方法可以返回线程的状态,当处于就绪、运行、等待、阻塞状态返回true,新建、死亡返回false。