关于线程的定义(摘自百度百科):
线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
JVM中定义的线程状态:
初始化状态NEW :源代码里面的注释解释为,线程创建,但是还未执行start()
Thread state for a thread which has not yet started.
可运行状态RUNABLE:源代码里面的注释解释为,执行start()之后,等待操作系统执行.PS:实际上RUNABLE可以拆分为两个,一个是准备就绪的状态,一个是运行中的状态.start()执行完是准备就绪,具体运行中取决于操作系统何时执行
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.
阻塞状态BLOCKED:源代码解释为:等待获取锁的过程,Object.wait()
* 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}.
等待状态WAIT:源代码解释为一个线程在等待另外一个线程执行完的一种状态,造成等待状态有以下三种情况:Object.wait();Thread.join();LockSupport.park();如一个线程通过Object.wait()进去等待状态,通过Object.nofity()唤醒重新进入RUNABLE.
* 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.
限时等待状态,TIMED_WATING:源代码解释造成这种状态的原因有五个,调用Thread.sleep(),Object.wait(long),Thread.join(long),lockSupport,parkNanos(),LockSupport.parkUntil()
* 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>
终止状态TERMINATED:源代码解释为线程执行完毕
Thread state for a terminated thread. The thread has completed execution.
关于状态变化的过程,代码如下:
package com.lyb269.thread;
import org.junit.Test;
public class ThreadStateTest {
@Test
public void startTest() throws InterruptedException {
System.out.println("== StartTest Start ==");
Thread t = new Thread(() ->{
String threadName = Thread.currentThread().getName();
System.out.println(threadName +" ---> Running");
});
System.out.println(t.getState().name()); //NEW 初始化
t.start();
System.out.println(t.getState().name()); // start(); 变为RUNNABLE 可执行
Long startTime = System.currentTimeMillis();
while (t.isAlive()){
//等待线程执行完毕
}
System.out.println(t.getName()+"执行使用了:"+(System.currentTimeMillis()-startTime)+"ms");
System.out.println(t.getState().name());
System.out.println("== StartTest End ==");
//打印结果
//== StartTest Start ==
//NEW 线程处于初始化的阶段
//RUNNABLE 调用start(), 程准备就绪,可运行,等待处理器分配资源执行
//Thread-0 ---> Running 线程执行
//Thread-0执行使用了:0ms 执行run方法使用时间
//TERMINATED 线程执行完毕
//== StartTest End ==
}
@Test
public void stateChangeProcessForTimeWait() throws InterruptedException{
Thread t = new Thread(() -> {
Thread currentThread = Thread.currentThread();
System.out.println("start()执行后;状态为:"+currentThread.getState().name());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sleep()执行后;状态为:"+currentThread.getState().name());
});
System.out.println("start()执行前;状态为:"+t.getState().name());
//start
t.start();
//另起一个线程,比线程t短,此线程sleep结束,t线程还在sleep
Thread.sleep(500);
System.out.println("sleep()执行过程中;状态为:"+t.getState().name());
while (t.isAlive()){
// 循环判断,直到线程执行结束
}
System.out.println("线程执行完毕;状态为:"+t.getState().name());
//start()执行前;状态为:NEW 初始化阶段:NEW
//start()执行后;状态为:RUNNABLE 可运行阶段:RUNNABLE
//sleep()执行过程中;状态为:TIMED_WAITING 主动sleep
//sleep()执行后;状态为:RUNNABLE 等待时长结束,恢复可运行阶段,等待CPU分配执行
//线程执行完毕;状态为:TERMINATED 执行结束
}
@Test
public void stateChangeProcessForWait() throws InterruptedException{
//定义一个锁,这里直接使用obj,用来加解锁
Object lock = new Object();
Thread t = new Thread(() -> {
Thread currentThread = Thread.currentThread();
System.out.println("start()执行后;状态为:"+currentThread.getState().name());
synchronized (lock){
try {
//模拟1秒业务操作
Thread.sleep(1000);
//wait,等待notify
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("notify()执行后;状态为:"+currentThread.getState().name());
});
System.out.println("start()执行前;状态为:"+t.getState().name());
//start
t.start();
//另起一个线程,比线程t长,保证t线程正常wait
Thread.sleep(1500);
System.out.println("wait()执行后;状态为:"+t.getState().name());
// notify
new Thread(() -> {
synchronized (lock){
// 唤醒
lock.notify();
}
}).start();
while (t.isAlive()){
// 循环判断,直到线程执行结束
}
System.out.println("线程执行完毕;状态为:"+t.getState().name());
//start()执行前;状态为:NEW 初始化阶段
//start()执行后;状态为:RUNNABLE 可运行阶段,等待操作系统执行
//wait()执行后;状态为:WAITING 释放锁,进入wait,等待notify
//notify()执行后;状态为:RUNNABLE notify,唤醒wait线程,重新变成可运行
//线程执行完毕;状态为:TERMINATED 执行结束
}
@Test
public void stateChangeProcessForBlock() throws InterruptedException{
//定义一个锁,这里直接使用obj,用来加解锁
Object lock = new Object();
new Thread(() -> {
synchronized (lock){
try {
//模拟业务逻辑,占用锁 2000ms
Thread.sleep(2000);
// 进入wait
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread t = new Thread(() -> {
Thread current = Thread.currentThread();
System.out.println("start()执行后;状态为:"+current.getState().name());
synchronized (lock){
try {
// 模拟业务,占用锁 1000ms
Thread.sleep(1000);
// 唤醒
lock.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("阻塞结束,线程的状态为:"+current.getState().name());
});
System.out.println("start()执行前;状态为:"+t.getState().name());
//start
t.start();
//此线程sleep结束,第一个线程还在sleep,t线程发在等待获取锁而阻塞
Thread.sleep(1000);
System.out.println("等待获取锁而阻塞;状态为:"+t.getState().name());
while (t.isAlive()){
// 循环判断,直到线程执行结束
}
System.out.println("线程执行完毕;状态为:"+t.getState().name());
//start()执行前;状态为:NEW 初始化阶段
//start()执行后;状态为:RUNNABLE 可运行阶段,等待操作系统执行
//等待获取锁而阻塞;状态为:BLOCKED 等待获取锁,而发生阻塞
//阻塞结束,线程的状态为:RUNNABLE 获取到锁,阻塞结束,变成可运行状态,等待执行
//线程执行完毕;状态为:TERMINATED 执行结束
}
}
盗用一张百度找到的图总结: