Java中sleep()與wait()區別
阿新 • • 發佈:2019-01-21
學習時正好碰到這兩個方法,就查閱相關資料,並通過程式實現,進行區別一下:
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()喚醒指定的執行緒或者所有執行緒,才會進入鎖池,不再次獲得物件鎖才會進入執行狀態;
以程式說明:
- publicclass MultiThread {
- privatestaticclass Thread1 implements Runnable{
- @Override
- publicvoid 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!");
- }
- }
- }
- privatestaticclass Thread2 implements Runnable{
- @Override
- publicvoid 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!");
- }
- }
- }
- publicstaticvoid main(String[] args) {
- new Thread(new Thread1()).start();
- try{
- Thread.sleep(10);
- }catch(InterruptedException e){
- e.printStackTrace();
- }
- new Thread(new Thread2()).start();
- }
- }
程式執行結果如下圖所示