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 ThreadTest {

    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();
    }


    public static class Thread1 implements Runnable {

        @Override
        public void run() {

            synchronized (ThreadTest.class) {
                System.out.println("進入thread1...");
                System.out.println("thread1是等待...");
                try {
                    //調用wait()方法,線程會放棄對象鎖,進入等待此對象的等待鎖定池
                    ThreadTest.class.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("thread1正在進行 ....");
                System.out.println("thread1結束!!!");
            }
        }


    }

    private static class Thread2 implements Runnable {

        @Override
        public void run() {
            synchronized (ThreadTest.class) {
                System.out.println("進入thread2...");
                System.out.println("thread2是睡眠");
                //只有針對此對象調用notify()方法后本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態。
                ThreadTest.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正在進行....");
            System.out.println("thread2結束!!!");
        }
    }


}

 

運行效果:

 

如果注釋掉代碼:

 ThreadTest.class.notify();

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM