JAVA線程sleep和wait方法區別

昨天面試,忽然被問到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)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。線程

相關文章
相關標籤/搜索