public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
/** * 程序目的:观察线程的各种状态 * created at 2020-06-26 19:09 * @author lerry */ class MyThread extends Thread { @Override public void run() { System.out.printf("%s线程运行\n", Thread.currentThread().getName()); } } /** * 分别观察创建线程后、start()后、和线程退出后的线程状态。 * 其中Thread.sleep(50);是为了等待线程执行完 */ public class ThreadStateDemo { public static void main(String[] args) throws InterruptedException { MyThread myThread = new MyThread(); System.out.printf("创建线程后,线程的状态为:%s\n", myThread.getState()); myThread.start(); System.out.printf("调用start()方法后线程的状态为:%s\n", myThread.getState()); // 休眠50毫秒,等待MyThread线程执行完 Thread.sleep(50); System.out.printf("再次打印线程的状态为:%s\n", myThread.getState()); } }
创建线程后,线程的状态为:NEW 调用start()方法后线程的状态为:RUNNABLE Thread-0线程运行 再次打印线程的状态为:TERMINATED
import lombok.extern.slf4j.Slf4j; /** * 程序目的:观察线程的BLOCKED状态 * created at 2020-06-26 19:09 * @author lerry */ @Slf4j public class ThreadBlockedStateDemo { public static void main(String[] args) { Thread threadA = new Thread(() -> method01(), "A-Thread"); Thread threadB = new Thread(() -> method01(), "B-Thread"); threadA.start(); threadB.start(); log.info("线程A的状态为:{}", threadA.getState()); log.info("线程B的状态为:{}", threadB.getState()); } /** * 停顿10毫秒、模拟方法执行耗时 */ public static synchronized void method01() { log.info("[{}]:开始执行主线程的方法", Thread.currentThread().getName()); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } log.info("[{}]:主线程的方法执行完毕", Thread.currentThread().getName()); } }
2020-06-26 20:32:15.404 [A-Thread] INFO com.hua.threadtest.state.ThreadBlockedStateDemo - [A-Thread]:开始执行主线程的方法 2020-06-26 20:32:15.404 [main ] INFO com.hua.threadtest.state.ThreadBlockedStateDemo - 线程A的状态为:RUNNABLE 2020-06-26 20:32:15.407 [main ] INFO com.hua.threadtest.state.ThreadBlockedStateDemo - 线程B的状态为:BLOCKED 2020-06-26 20:32:15.417 [A-Thread] INFO com.hua.threadtest.state.ThreadBlockedStateDemo - [A-Thread]:主线程的方法执行完毕 2020-06-26 20:32:15.418 [B-Thread] INFO com.hua.threadtest.state.ThreadBlockedStateDemo - [B-Thread]:开始执行主线程的方法 2020-06-26 20:32:15.430 [B-Thread] INFO com.hua.threadtest.state.ThreadBlockedStateDemo - [B-Thread]:主线程的方法执行完毕
import lombok.extern.slf4j.Slf4j; /** * <pre> * 程序目的:观察线程的WAITING状态 * 模拟:只有一个售票窗口的售票厅,有两个粉丝都想买票。 * 如果没有票,他们就继续等待、如果有票,则买票、然后离开售票厅。 * 其中,工作人员会补票,补票之后,粉丝就可以买到票了。 * </pre> * created at 2020-06-26 19:09 * @author lerry */ @Slf4j public class ThreadWaitingStateDemo { public static void main(String[] args) throws InterruptedException { Ticket ticket = new Ticket(); Thread threadA = new Thread(() -> { synchronized (ticket) { while (ticket.getNum() == 0) { try { ticket.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } ticket.buy(); } }, "粉丝A"); Thread threadB = new Thread(() -> { synchronized (ticket) { while (ticket.getNum() == 0) { try { ticket.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } ticket.buy(); } }, "粉丝B"); threadA.start(); threadB.start(); // 确保A和B线程都运行起来 Thread.sleep(10); log.info("粉丝A线程的状态为:{}", threadA.getState()); log.info("粉丝B线程的状态为:{}", threadB.getState()); Thread employeeThread = new Thread(() -> { synchronized (ticket) { if (ticket.getNum() == 0) { ticket.addTickt(); ticket.notifyAll(); } } }, "补票员"); employeeThread.start(); } } @Slf4j class Ticket { /** * 票的张数 */ private int num = 0; public int getNum() { return num; } public void addTickt() { try { Thread.sleep(2_000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("补充票"); this.num = 2; } /** * 停顿10毫秒、模拟方法执行耗时 */ public void buy() { log.info("[{}]:购买了一张票", Thread.currentThread().getName()); log.info("[{}]:退出售票厅", Thread.currentThread().getName()); } }
2020-06-26 21:26:37.938 [main ] INFO com.hua.threadtest.state.ThreadWaitingStateDemo - 粉丝A线程的状态为:WAITING 2020-06-26 21:26:37.945 [main ] INFO com.hua.threadtest.state.ThreadWaitingStateDemo - 粉丝B线程的状态为:WAITING 2020-06-26 21:26:39.948 [补票员 ] INFO com.hua.threadtest.state.Ticket - 补充票 2020-06-26 21:26:39.949 [粉丝B ] INFO com.hua.threadtest.state.Ticket - [粉丝B]:购买了一张票 2020-06-26 21:26:39.949 [粉丝B ] INFO com.hua.threadtest.state.Ticket - [粉丝B]:退出售票厅 2020-06-26 21:26:39.949 [粉丝A ] INFO com.hua.threadtest.state.Ticket - [粉丝A]:购买了一张票 2020-06-26 21:26:39.949 [粉丝A ] INFO com.hua.threadtest.state.Ticket - [粉丝A]:退出售票厅
2020-06-26 21:27:10.704 [main ] INFO com.hua.threadtest.state.ThreadWaitingStateDemo - 粉丝A线程的状态为:TIMED_WAITING 2020-06-26 21:27:10.709 [main ] INFO com.hua.threadtest.state.ThreadWaitingStateDemo - 粉丝B线程的状态为:TIMED_WAITING 2020-06-26 21:27:12.714 [补票员 ] INFO com.hua.threadtest.state.Ticket - 补充票 2020-06-26 21:27:12.714 [粉丝B ] INFO com.hua.threadtest.state.Ticket - [粉丝B]:购买了一张票 2020-06-26 21:27:12.714 [粉丝B ] INFO com.hua.threadtest.state.Ticket - [粉丝B]:退出售票厅 2020-06-26 21:27:12.715 [粉丝A ] INFO com.hua.threadtest.state.Ticket - [粉丝A]:购买了一张票 2020-06-26 21:27:12.715 [粉丝A ] INFO com.hua.threadtest.state.Ticket - [粉丝A]:退出售票厅
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop: synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }