線程狀態:java
狀態轉換圖:ide
線程狀態轉換函數:函數
狀態轉換示例:oop
定義一個WaitRunnable線程對象,在run()方法中加鎖並調用wait()方法模擬等待資源。線程
public class WaitRunnable implements Runnable{ @Override public void run() { System.out.printf("%s:開始執行,準備鎖定object。\n", Thread.currentThread().getName()); synchronized (Main.object) { try { System.out.printf("%s:成功鎖定object,執行同步模塊。\n", Thread.currentThread().getName()); Thread.sleep(3000); System.out.printf("%s:被掛起,等待其餘線程喚醒本身。\n", Thread.currentThread().getName()); Main.object.wait(); System.out.printf("%s: 被喚起,繼續開始執行。\n", Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.printf("%s: 執行結束。", Thread.currentThread().getName()); } }
定義一個NotifyRunnable線程對象,在run()方法中加鎖,並調用notify()方法來喚醒WaitRunnable線程。日誌
package oschian.section_03; /** * Created by hadoop on 2016/11/22. */ public class NotifyRunnable implements Runnable { @Override public void run() { System.out.printf("%s:開始執行,準備鎖定object。\n", Thread.currentThread().getName()); synchronized (Main.object) { System.out.printf("%s:成功鎖定object,執行同步模塊。\n", Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("%s: 喚醒其餘線程。\n", Thread.currentThread().getName()); Main.object.notify(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.printf("%s: 執行結束。\n", Thread.currentThread().getName()); } }
定義主方法類,啓動兩個線程,並打印線程狀態。code
public class Main { public static final Object object = new Object(); public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new WaitRunnable()); Thread thread2 = new Thread(new NotifyRunnable()); System.out.printf("Main: %s:%s , %s:%s\n", thread1.getName(), thread1.getState(), thread2.getName(), thread2.getState()); thread1.start(); thread2.start(); while (thread1.getState() != Thread.State.TERMINATED || thread2.getState() != Thread.State.TERMINATED) { System.out.printf("Main: %s:%s , %s:%s\n", thread1.getName(), thread1.getState(), thread2.getName(), thread2.getState()); Thread.sleep(1000); } } }
查看控制檯日誌:對象
Main: Thread-0:NEW , Thread-1:NEW Thread-0:開始執行,準備鎖定object。 Thread-0:成功鎖定object,執行同步模塊。 Main: Thread-0:TIMED_WAITING , Thread-1:RUNNABLE Thread-1:開始執行,準備鎖定object。 Main: Thread-0:TIMED_WAITING , Thread-1:BLOCKED Main: Thread-0:TIMED_WAITING , Thread-1:BLOCKED Thread-0:被掛起,等待其餘線程喚醒本身。 Thread-1:成功鎖定object,執行同步模塊。 Main: Thread-0:WAITING , Thread-1:TIMED_WAITING Main: Thread-0:WAITING , Thread-1:TIMED_WAITING Main: Thread-0:WAITING , Thread-1:TIMED_WAITING Thread-1: 喚醒其餘線程。Main: Thread-0:BLOCKED , Thread-1:TIMED_WAITING Main: Thread-0:BLOCKED , Thread-1:TIMED_WAITING Main: Thread-0:BLOCKED , Thread-1:TIMED_WAITING Thread-1: 執行結束。Thread-0: 被喚起,繼續開始執行。Thread-0: 執行結束。
執行過程分析:內存
1. Thread-0與Thread-1建立之初。hadoop
2. Thread-0先啓動,獲取鎖後進入同步方法快並調用sleep方法等待3秒。Thread-1接着啓動,也嘗試獲取鎖,可是鎖已經被Thread-0獲取,Thread-1等待鎖釋放。
3. Thread-0等待3秒後繼續執行而後調用wait方法掛起,並釋放鎖。Thread-1獲取到鎖後開始執行同步快並等待三秒。
4. Thread-1休眠3秒後喚醒Thread-0,但這個時候鎖依然被Thread-1所擁有,而後Thread-1繼續休眠3秒。Thread-0等待Thread-1釋放鎖。
5. Thread-1休眠結束後恢復,並執行完畢同步方法快後結束。Thread-0獲取鎖後恢復,執行完同步方法快後結束。