1. 程式人生 > >wait(1000)與sleep(1000)的區別

wait(1000)與sleep(1000)的區別

sleep和wait的區別:

1、sleep是Thread的靜態方法,wait是Object的方法,任何物件例項都能呼叫。

2、sleep不會釋放鎖,它也不需要佔用鎖。wait會釋放鎖,但呼叫它的前提是當前執行緒佔有鎖(即程式碼要在synchronized中)。

3、它們都可以被interrupted方法中斷。

具體來說:

Thread.Sleep(1000) 意思是在未來的1000毫秒內本執行緒不參與CPU競爭,1000毫秒過去之後,這時候也許另外一個執行緒正在使用CPU,那麼這時候作業系統是不會重新分配CPU的,直到那個執行緒掛起或結束,即使這個時候恰巧輪到作業系統進行CPU 分配,那麼當前執行緒也不一定就是總優先順序最高的那個,

CPU還是可能被其他執行緒搶佔去。另外值得一提的是Thread.Sleep(0)的作用,就是觸發作業系統立刻重新進行一次CPU競爭,競爭的結果也許是當前執行緒仍然獲得CPU控制權,也許會換成別的執行緒獲得CPU控制權。

wait(1000)表示將鎖釋放1000毫秒,到時間後如果鎖沒有被其他執行緒佔用,則再次得到鎖,然後wait方法結束,執行後面的程式碼,如果鎖被其他執行緒佔用,則等待其他執行緒釋放鎖。注意,設定了超時時間的wait方法一旦過了超時時間,並不需要其他執行緒執行notify也能自動解除阻塞,但是如果沒設定超時時間的wait方法必須等待其他執行緒執行notify

package testThread;

/**
 * 
 * @author wuwenhai
 * @since JDK1.6
 * @history 2017-8-3 wuwenhai 新建
 */
public class testWait {

    public static void main(String[] args) {
        Integer i=new Integer(1);
        new Thread(new waitThread(i)).start();
        new Thread(new notifyThread(i)).start();
    }
}
class waitThread implements Runnable{

    Integer i;
    
    public waitThread(Integer i) {
        super();
        this.i = i;
    }

    @Override
    public void run() {
        try {
            synchronized(i){
                long start =System.currentTimeMillis();
                i.wait(1000);
                System.out.println("waitThread "+(System.currentTimeMillis()-start)+" done");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
}

class notifyThread implements Runnable{

    Integer i;
    
    public notifyThread(Integer i) {
        super();
        this.i = i;
    }

    @Override
    public void run() {
        try {
            long start =System.currentTimeMillis();
            Thread.sleep(500);//如果此處設成1500,因為sleep沒有佔有鎖,wait方法在1000ms後會自動再次獲得鎖然後解除阻塞執行。
            synchronized(i){
                Thread.sleep(1500);
                i.notify();//如果wait過了超時時間,無論有無notify,wait都會自動解除阻塞,即該句可以註釋,不影響結果。但是如果wait沒有設定超時時間,該句必須存在,否則waitThread用於處於阻塞狀態。
                System.out.println("notifyThread "+(System.currentTimeMillis()-start)+" done");
            }
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }        
    }
}