一. 介紹 sleep() : 是Thread類方法,用於使當前線程暫停執行一段時間。它可以被使用在多線程編程中,用於控制線程的執行速度或者創建時間延遲。 參數: long millis : 參數表示線程休眠的毫秒數。 例如,如果調用Thread.sleep(1000),則當前線程會休眠 1000 ...
一. 介紹
sleep() : 是Thread類方法,用於使當前線程暫停執行一段時間。它可以被使用在多線程編程中,用於控制線程的執行速度或者創建時間延遲。
參數: long millis : 參數表示線程休眠的毫秒數。 例如,如果調用Thread.sleep(1000),則當前線程會休眠 1000 毫秒(即 1 秒);
int nanos : 參數nanos表示要暫停的時間長度的額外部分,以納秒為單位 ;
wait() : 是Object類的方法,讓當前線程進入等待(阻塞)WAITTING 狀態,將線程放入到等待隊列中,並釋放對象鎖。
參數 long timeout: 參數timeout(毫秒)時間後會被自動喚醒 ;
int nanos : 參數nanos表示額外時間(以毫微秒為單位,範圍是 0-999999);wait(500, 50000),先執行5000毫微秒,執行結束後調用timeout執行。
二. 代碼展示
public static void main(String[] args) { Object o = new Object(); long start = System.currentTimeMillis(); // 開啟一個線程,線程內部使用wait() 方法 釋放線程並讓線程進入等待。 new Thread(() -> { System.out.println("我是wait()線程"); synchronized (o) { System.out.println("線程wait()等待將執行"); try { System.out.println("線程wait() 已釋放"); o.wait(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("線程wait()已喚醒,執行完畢,執行時間:" + (end - start)); } }).start(); // 開啟一個線程,用於執行sleep()方法,使其線程暫時休眠。 new Thread(() -> { System.out.println("我是Thread.sleep線程"); synchronized (o) { System.out.println("線程Thread.sleep執行中"); try { Thread.sleep(5000); o.notify(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("線程Thread.sleep執行結束,用時" + (end - start)); } }).start(); }
執行過程:
- new 兩個Thread線程類 ,通過start() 方法執行,開啟搶占式;
- 使用 synchronized 關鍵字,鎖定執行線程。
- 假設wait() 搶到線程調度,將會執行o.wait(); 釋放該線程鎖,進入等待狀態,此時該線程不會自動喚醒,需要等待o.notify()或o.notifyAll() 方法,wait()線程才會重新進入就緒狀態,準備獲得對象鎖進入運行狀態
- Thread.sleep線程,會在o.wait() 方法執行後,獲取到線權,執行Thread.sleep() 方法,該方法不會釋放線程,會導致線程暫停執行,監控狀態依然保持,在達到指定執行時間後會自動恢復。
- Thread.sleep線程恢復後,將執行o.notify() 方法(當前線程不會馬上釋放該對象鎖,要等到同步塊或者同步方法執行完後,當前線程才會釋放鎖),喚醒 wait() 線程,順序執行代碼後結束;
- wait()線程進入運行狀態,順序執行代碼後結束。
三. 區別
sleep:是指讓當前線程暫停執行一段時間(即睡眠),然後再繼續執行。在睡眠期間,線程會進入阻塞狀態,不會占用CPU資源。sleep 的作用是為了暫停程式的執行,通常用於實現時間延遲的需求或控製程序的執行頻率。
wait:是指在多線程編程中,調用對象的某個方法,使當前線程等待,直到其他線程通知或滿足特定條件時再繼續執行。在調用 wait 方法後,當前線程會釋放鎖併進入等待狀態,直到其他線程通過調用對象的 notify 或 notifyAll 方法來喚醒等待的線程。
總結: sleep 是線程級別的操作,可以讓當前線程暫停一段時間。
wait 是對象級別的操作,使當前線程等待其他線程的通知或特定條件的滿足。
四. 拓展
1. 線程的狀態:
創建狀態: 當用new操作符創建一個線程的時候
就緒狀態: 調用start方法,處於就緒狀態的線程並不一定馬上就執行run方法,還需要等待CPU的調度。
運行狀態: CPU開始調度線程,並開始執行Run方法。
阻塞狀態: 線程的執行過程中可能因為一些原因進入阻塞狀態,比如調用sleep方法,獲取嘗試得到一個等待。
等待狀態(Waiting): 使用notify、notifyAll、join方法喚醒。
死亡狀態: Run方法執行完成或者執行終於遇到異常。
2. Thread.sleep(1000) 和 o.wait(1000) 的區別;
兩者參數均為1s,也就是多,兩者執行都會等待1s,但有本質上的區別
Thread.sleep() 在暫停期間,線程不會釋放持有的任何鎖或資源。一旦暫停時間結束,線程將被喚醒並可以重新參與競爭執行。
wait()方法,必須在一個同步代碼塊或同步方法中,並且線程必須獲取到對象的監視器鎖。wait()方法調用後,線程進入等待狀態並釋放持有的監視器鎖。其他線程可以進入該對象的同步代碼塊或同步方法,並對其進行操作。當滿足某個條件時,或者超過最長等待時間後,線程將被喚醒並嘗試重新獲取監視器鎖以繼續執行。
完