Java中sleep與wait的區別
學習時正好碰到這兩個方法,就查閱相關資料,並通過程式實現,進行區別一下:
1、每個物件都有一個鎖來控制同步訪問,Synchronized關鍵字可以和物件的鎖互動,來實現同步方法或同步塊。sleep()方法正在執行的執行緒主動讓出CPU(然後CPU就可以去執行其他任務),在sleep指定時間後CPU再回到該執行緒繼續往下執行(注意:sleep方法只讓出了CPU,而並不會釋放同步資源鎖!!!);wait()方法則是指當前執行緒讓自己暫時退讓出同步資源鎖,以便其他正在等待該資源的執行緒得到該資源進而執行,只有呼叫了notify()方法,之前呼叫wait()的執行緒才會解除wait狀態,可以去參與競爭同步資源鎖,進而得到執行。(注意:notify的作用相當於叫醒睡著的人,而並不會給他分配任務,就是說notify只是讓之前呼叫wait的執行緒有權利重新參與執行緒的排程
2、sleep()方法可以在任何地方使用;wait()方法則只能在同步方法或同步塊中使用;
3、sleep()是執行緒執行緒類(Thread)的方法,呼叫會暫停此執行緒指定的時間,但監控依然保持,不會釋放物件鎖,到時間自動恢復;wait()是Object的方法,呼叫會放棄物件鎖,進入等待佇列,待呼叫notify()/notifyAll()喚醒指定的執行緒或者所有執行緒,才會進入鎖池,不再次獲得物件鎖才會進入執行狀態;
public class MultiThread {
private static class Thread1 implements Runnable{
@Override
public void run() {
//由於 Thread1和下面Thread2內部run方法要用同一物件作為監視器,如果用this則Thread1和Threa2的this不是同一物件
//所以用MultiThread.class這個位元組碼物件,當前虛擬機器裡引用這個變數時指向的都是同一個物件
synchronized(MultiThread.class){
System.out.println("enter thread1 ...");
System.out.println("thread1 is waiting");
try{
//釋放鎖有兩種方式:(1)程式自然離開監視器的範圍,即離開synchronized關鍵字管轄的程式碼範圍
//(2)在synchronized關鍵字管轄的程式碼內部呼叫監視器物件的wait()方法。這裡使用wait方法
MultiThread.class.wait();
}catch(InterruptedException e){
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() {
//notify方法並不釋放鎖,即使thread2呼叫了下面的sleep方法休息10ms,但thread1仍然不會執行
//因為thread2沒有釋放鎖,所以Thread1得不到鎖而無法執行
synchronized(MultiThread.class){
System.out.println("enter thread2 ...");
System.out.println("thread2 notify other thread can release wait status ...");
MultiThread.class.notify();
System.out.println("thread2 is sleeping ten millisecond ...");
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("thread2 is going on ...");
System.out.println("thread2 is being over!");
}
}
}
public static void main(String[] args) {
new Thread(new Thread1()).start();
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
new Thread(new Thread2()).start();
}
}