java sleep()和wait()的區別
java sleep()和wait()的區別?
sleep()和wait()都能阻塞當前線程。
區別1:
sleep()屬於Thread類;wait()屬於Object類。
區別2:
調用sleep()方法的過程中,線程不會釋放對象鎖。
調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池準備獲取對象鎖進入運行狀態。
打個比較有味道的比喻:sleep和wait兩個小朋友在拉屎,然後老師說你們兩個不要拉屎了,wait小朋友乖乖地聽話提起褲子從廁所裏面出來了;sleep小朋友也很聽話,也先不拉屎了,但是呢就是不從廁所出來;老師對sleep小朋友也沒辦法,只好不管他了,然後一扭頭看到wait小朋友臉憋得通紅,只得讓wait小朋友繼續去廁所;此時廁所已經有人了,wait小朋友只好重新排隊;sleep小朋友在廁所聽到老師走了也就繼續他的事業了。
這裏的兩個小朋友就是線程,廁所就是對象鎖。
看個示例程序:
public class MyTest { public static void main(String[] args) throws InterruptedException { Object o = new Object(); Thread t1 = new Thread(() -> { synchronized (o) { System.out.println("start t1"); try { o.wait(); } catch (InterruptedException e) { } System.out.println("end t1"); } }); Thread t2 = new Thread(() -> { synchronized (o) { System.out.println("start t2"); try { o.notify(); Thread.sleep(100L); System.out.println("t2 sleep 100 mills"); } catch (Exception e) { } } System.out.println("t2 sleep 200 mills"); try { Thread.sleep(200L); } catch (InterruptedException e) { } System.out.println("end t2"); }); t1.start(); Thread.sleep(10L); t2.start(); } }
執行結果如下:
start t1 start t2 t2 sleep 100 mills end t1 t2 sleep 200 mills end t2
兩個線程執行過程如下:
1. 線程1先開始執行,獲得對象鎖o,輸出一行字符後隨即被wait方法阻塞,釋放對象鎖o;
2. 線程2開始執行,獲得線程1釋放的對象鎖o,輸出一行字符後調用對象鎖o的notify方法喚醒線程1;
3. 線程2開始sleep,但此時線程2仍持有對象鎖o,線程1雖已被喚醒但無法獲得對象鎖o只好繼續阻塞;
4. 線程2 sleep結束,輸出一行字符,釋放對象o,隨即輸出一行字符,然後繼續sleep;
5. 線程1得到對象鎖,結束阻塞狀態,繼續執行直到結束;
6. 線程2 sleep結束,繼續執行直到結束。
從這個過程中可以了解sleep和wait的區別與使用方法。
再看一個基於wait方法實現的簡單鎖:
public class MyLock { private boolean flag = false; public void lock() { synchronized (this) { while (flag) { try { wait();// 已經加鎖,當前線程需要等待 } catch (InterruptedException e) { } } flag = true; } } public void unlock() { synchronized (this) { flag = false; notifyAll();// 釋放鎖時通知其他線程 } } }
java sleep()和wait()的區別