昨天面試,忽然被問到sleep 和 wait的區別,一會兒有點蒙,在這裏記一下,以示警惕。java
首先說sleep,sleep就是正在執行的線程主動讓出cpu,cpu去執行其餘線程,在sleep指定的時間過去後,cpu纔會回到這個線程繼續往下執行,若是當前線程進入了同步鎖,sleep方法並不會釋放鎖,即便當前線程使用sleep方法讓出了cpu,但其餘被同步鎖擋住了的線程也沒法獲得執行。面試
再說wait,wait是指一個已經進入了同步鎖的線程內,讓本身暫時讓出同步鎖,以便其餘正在等待此鎖的線程能夠獲得同步鎖並運行,只有其餘調用了notify方法(notify並不釋放鎖,只是告訴調用過wait方法的線程能夠去參與得到鎖的競爭了,但不是立刻獲得鎖,由於鎖還在別人手裏,別人還沒釋放。若是notify方法後面的代碼還有不少,須要這些代碼執行完後纔會釋放鎖,能夠在notfiy方法後增長一個等待和一些代碼,看看效果),調用wait方法的線程就會解除wait狀態和程序能夠再次獲得鎖後繼續向下運行.說了這麼多,仍是看代碼比較直接,貼代碼:ide
public class MultiThread { public static void main(String[] args) { new Thread(new Thread1()).start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } new Thread(new Thread2()).start(); } private static class Thread1 implements Runnable { @Override public void run() { // TODO Auto-generated method stub // 因爲這裏的Thread1和下面的Thread2內部run方法要用同一對象做爲監視器, // 咱們這裏不能用this,由於在Thread2裏面的this和這個Thread1的this不是同一個對象。 // 咱們用MultiThread.class這個字節碼對象,當前虛擬機裏引用這個變量時,指向的都是同一個對象。 synchronized (MultiThread.class) { System.out.println("enter thread1..."); System.out.println("thread1 is waiting"); try { // 釋放鎖有兩種方式,第一種方式是程序天然離開監視器的範圍,也就是離開了synchronized關鍵字管轄的代碼範圍, //另外一種方式就是在synchronized關鍵字管轄的代碼內部調用監視器對象的wait方法。這裏,使用wait方法釋放鎖。 MultiThread.class.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("thread1 is going on..."); System.out.println("thread1 is being over!"); } } } private static class Thread2 implements Runnable { @Override public void run() { // TODO Auto-generated method stub synchronized (MultiThread.class) { System.out.println("enter thread2..."); System.out.println("thread2 notify other thread can release wait status.."); // 因爲notify方法並不釋放鎖, // 即便thread2調用下面的sleep方法休息了10毫秒,但thread1仍然不會執行,由於thread2沒有釋放鎖,因此Thread1沒法得不到鎖。 MultiThread.class.notify(); System.out.println("thread2 is sleeping ten millisecond..."); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("thread2 is going on..."); System.out.println("thread2 is being over!"); } } } }
下面是我搜到了一些網上答案,也放在下面,這個主要仍是靠本身去理解:this
sleep是線程類(Thread)的方法,致使此線程暫停執行指定時間,給執行機會給其餘線程,可是監控狀態依然保持,到時後會自動恢復。調用sleep不會釋放對象鎖。wait是Object類的方法,對此對象調用wait方法致使本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify方法(或notifyAll)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。線程