java中wait和sleep的區別
A. java中Wait,Sleep和Yield方法的區別
共同點:
1. 他們都是在多線程的環境下,都可以在程序的調用處阻塞指定的毫秒數,並返回。
2. wait()和sleep()都可以通過interrupt()方法 打斷線程的暫停狀態 ,從而使線程立刻拋出InterruptedException。
如果線程A希望立即結束線程B,則可以對線程B對應的Thread實例調用interrupt方法。如果此刻線程B正在wait/sleep/join,則線程B會立刻拋出InterruptedException,在catch() {} 中直接return即可安全地結束線程。
需要注意的是,InterruptedException是線程自己從內部拋出的,並不是interrupt()方法拋出的。對某一線程調用 interrupt()時,如果該線程正在執行普通的代碼,那麼該線程根本就不會拋出InterruptedException。但是,一旦該線程進入到 wait()/sleep()/join()後,就會立刻拋出InterruptedException 。
不同點:
1. Thread類的方法:sleep(),yield()等
Object的方法:wait()和notify()等
2. 每個對象都有一個鎖來控制同步訪問。Synchronized關鍵字可以和對象的鎖交互,來實現線程的同步。
sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。
3. wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用
4. sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常
B. java裡面的wait方法(object類中的)和sleep()方法有什麼本質上的區別,詳解1··
首先,sleep()是Thread類中的方法,而wait()則是Object類中的方法。
sleep()方法導致了程序暫停,但是他的監控狀態依然保持著,當指定的時間到了又會自動恢復運行狀態。在調用sleep()方法的過程中,線程不會釋放對象鎖。
wait()方法會導致線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態。
以下以代碼為例講解:
package test;
public class WaitAndSleep {
public static void main(String[] args) {
new Thread(new Thread1()).start();
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
new Thread(new Thread2()).start();
}
private static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (WaitAndSleep.class) {
System.out.println("thread1 is waiting...");
try {
// 調用wait()方法,線程會放棄對象鎖,進入等待此對象的等待鎖定池
WaitAndSleep.class.wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("thread1 is going on ....");
System.out.println("thread1 is over!!!");
}
}
}
private static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (WaitAndSleep.class) {
System.out.println("enter thread2....");
System.out.println("thread2 is sleep....");
// 只有針對此對象調用notify()方法後本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態。
WaitAndSleep.class.notify();
// ==================
// 區別
// 如果我們把代碼:TestD.class.notify();給注釋掉,即TestD.class調用了wait()方法,但是沒有調用notify()
// 方法,則線程永遠處於掛起狀態。
try {
// sleep()方法導致了程序暫停執行指定的時間,讓出cpu該其他線程,
// 但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態。
// 在調用sleep()方法的過程中,線程不會釋放對象鎖。
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("thread2 is going on....");
System.out.println("thread2 is over!!!");
}
}
}
}
運行結果:
thread1 is waiting...
enter thread2....
thread2 is sleep....
thread2 is going on....
thread2 is over!!!
thread1 is going on ....
thread1 is over!!!
如果我們把代碼:WaitAndSleep.class.notify();給注釋掉
運行結果:
thread1 is waiting...
enter thread2....
thread2 is sleep....
thread2 is going on....
thread2 is over!!!
程序一直處於掛起狀態,無法結束
C. java的sleep()和wait()
wait()、notify()、notifyAll()這三個方法是Object中的方法,跟鎖類似。
當t1沒有獲取這個object時wait,其他線程釋放object後叫notify,然後t1立即繼續執行。
sleep()跟上面這三個不一樣,是Thread中的方法,不需要等待資源被釋放,sleep有一個時間傳參,想讓線程等待多會兒就等待多會兒,不需要其他線程喚醒。例如:
try{
t1.sleep(1000); //t1等待1秒後繼續執行下面的內容
}catch(Exception e){}