前文《Java多线程-基础篇-1.什么是多线程》已经说明了线程的状态以及线程状态的切换规则。本文将采用实例演示线程之间状态的切换。 

1.TIME_WAITING状态

package com.lreis.learing.thread.state;

public class ThreadState_TimeWaiting extends Thread {

	public static void main(String[] args) throws InterruptedException {

		// 线程状态间的状态转换:NEW->RUNNABLE->TIME_WAITING->RUNNABLE->TERMINATED
		System.out.println("======线程状态间的状态转换NEW->RUNNABLE->TIME_WAITING->RUNNABLE->TERMINATED======");
		// 定义一个内部线程
		Thread thread = new Thread(() -> {
			System.out.println("2.执行thread.start()之后,线程的状态:" + Thread.currentThread().getState());
			try {
				// 休眠100毫秒
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("4.执行Thread.sleep(long)完成之后,线程的状态:" + Thread.currentThread().getState());
		});
		// 获取start()之前的状态
		System.out.println("1.通过new初始化一个线程,但是还没有start()之前,线程的状态:" + thread.getState());
		// 启动线程
		thread.start();
		// 休眠50毫秒
		Thread.sleep(50);
		// 因为thread1需要休眠100毫秒,所以在第50毫秒,thread1处于sleep状态
		System.out.println("3.执行Thread.sleep(long)时,线程的状态:" + thread.getState());
		// thread1和main线程主动休眠150毫秒,所以在第150毫秒,thread1早已执行完毕
		Thread.sleep(100);
		System.out.println("5.线程执行完毕之后,线程的状态:" + thread.getState() + "\n");
	}

}

造成TIME_WAITING状态的方式有Thread.sleep(long)、Object.wait(long)、Object.wait(long)、join(long)、LockSupport.parkNanos(obj,long)和LockSupport.parkUtil(obj,long)。

说明

  1. 线程运行状态和可运行状态使用的是同一状态RUNNABLE;
  2. 线程调用sleep(long)后完成RUNNABLE状态到TIME_WAITING状态的切换。

2.WAITING状态

package com.lreis.learing.thread.state;

import java.util.concurrent.atomic.AtomicBoolean;

public class ThreadState_Waiting extends Thread {

	public static void main(String[] args) throws InterruptedException {
		// 线程状态间的状态转换:NEW->RUNNABLE->WAITING->RUNNABLE->TERMINATED
		System.out.println("======线程状态间的状态转换NEW->RUNNABLE->WAITING->RUNNABLE->TERMINATED======");
		// 定义一个对象,用来加锁和解锁
		AtomicBoolean lock = new AtomicBoolean(false);
		// 定义一个内部线程
		Thread thread1 = new Thread(() -> {
			System.out.println("2.执行thread.start()之后,线程的状态:" + Thread.currentThread().getState());
			synchronized (lock) {
				try {
					// thread1需要休眠100毫秒
					Thread.sleep(100);
					// thread1100毫秒之后,通过wait()方法释放obj对象是锁
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("4.被object.notify()方法唤醒之后,线程的状态:" + Thread.currentThread().getState());
		});
		// 获取start()之前的状态
		System.out.println("1.通过new初始化一个线程,但是还没有start()之前,线程的状态:" + thread1.getState());
		// 启动线程
		thread1.start();
		// main线程休眠150毫秒
		Thread.sleep(150);
		// 因为thread1在第100毫秒进入wait等待状态,所以第150秒肯定可以获取其状态
		System.out.println("3.执行object.wait()时,线程的状态:" + thread1.getState());
		// 声明另一个线程进行解锁
		new Thread(() -> {
			synchronized (lock) {
				// 唤醒等待的线程
				lock.notify();
			}
		}).start();
		// main线程休眠10毫秒等待thread1线程能够苏醒
		Thread.sleep(10);
		// 获取thread1运行结束之后的状态
		System.out.println("5.线程执行完毕之后,线程的状态:" + thread1.getState() + "\n");
	}

}

造成WAIT状态的方式有Thread.wait()、join()、LockSupport.park()方法。

Java线程状态及转换 java线程切换_Java

3.BLOCKED状态

package com.lreis.learing.thread.state;

import java.util.concurrent.atomic.AtomicBoolean;

public class ThreadState_Blocked {

	public static void main(String[] args) throws InterruptedException {
		// 线程状态间的状态转换:NEW->RUNNABLE->BLOCKED->RUNNABLE->TERMINATED
		System.out.println("======线程状态间的状态转换NEW->RUNNABLE->BLOCKED->RUNNABLE->TERMINATED======");
		// 定义一个对象,用来加锁和解锁
		AtomicBoolean obj2 = new AtomicBoolean(false);
		// 定义一个线程,先抢占了obj2对象的锁
		new Thread(() -> {
			synchronized (obj2) {
				try {
					// 第一个线程要持有锁100毫秒
					Thread.sleep(100);
					// 然后通过wait()方法进行等待状态,并释放obj2的对象锁
					obj2.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
		// 定义目标线程,获取等待获取obj2的锁
		Thread thread3 = new Thread(() -> {
			System.out.println("2.执行thread.start()之后,线程的状态:" + Thread.currentThread().getState());
			synchronized (obj2) {
				try {
					// thread3要持有对象锁100毫秒
					Thread.sleep(100);
					// 然后通过notify()方法唤醒所有在ojb2上等待的线程继续执行后续操作
					obj2.notify();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println("4.阻塞结束后,线程的状态:" + Thread.currentThread().getState());
		});
		// 获取start()之前的状态
		System.out.println("1.通过new初始化一个线程,但是还没有thread.start()之前,线程的状态:" + thread3.getState());
		// 启动线程
		thread3.start();
		// 先等100毫秒
		Thread.sleep(50);
		// 第一个线程释放锁至少需要100毫秒,所以在第50毫秒时,thread3正在因等待obj的对象锁而阻塞
		System.out.println("3.因为等待锁而阻塞时,线程的状态:" + thread3.getState());
		// 再等300毫秒
		Thread.sleep(300);
		// 两个线程的执行时间加上之前等待的50毫秒以供250毫秒,所以第300毫秒,所有的线程都已经执行完毕
		System.out.println("5.线程执行完毕之后,线程的状态:" + thread3.getState());

	}

}

BLOCKED状态是不能拿到synchronized对象锁而处于等待状态。

Java线程状态及转换 java线程切换_多线程_02