notify()和wait()


  

原創:轉載需注明原創地址 https://www.cnblogs.com/fanerwei222/p/11398563.html

 

  notify() 和 wait() 主要是用來多個線程之間的協作。

  它們都是Object的方法,任何對象都可以調用這兩個方法。

  首先設置一個多個線程共享的對象 :

 

//共享對象
Object shareObject = new Object();

 

  1.wait() :導致當前線程等待,直到另一個線程調用該對象的notify()或者notifyAll()方法;

  這里用代碼解釋一下:

class ThreadOne extends Thread{
        @Override
        public void run() {
            synchronized (shareObject){
                for (int i = 0; i < 10 ; i++){
                    System.out.println("A線程--->"+i);
                    shareObject.notify();
                    if (first){
                        first = false;
                        try {
                            shareObject.wait();
                        } catch (Exception e){
                            System.out.println(e);
                        }
                    }
                }
            }
        }
    }

  這里的 shareObject.wait(); 會導致ThreadOne線程進入shareObject對象的等待隊列(這個等待隊列可能會有多個線程,這些線程都停止繼續執行,進入等待狀態),直到其他線程調用shareObject的notify()或者notifyAll()方法,ThreadOne線程就可能會被喚醒,因為該喚醒是從等待隊列中隨機抽取一個線程進行喚醒,不公平喚醒。

  2.notify() :喚醒正在等待對象監視器的單個線程。這個在上面已經作了解釋,下面用代碼說明一下。

class ThreadTwo extends Thread{
        @Override
        public void run() {
            synchronized (shareObject){
                for (int i = 0; i < 10; i++){
                    System.out.println("B線程--->"+i);
                    shareObject.notify();
                    if (!first){
                        first = true;
                        try {
                            shareObject.wait();
                        }catch (Exception e){
                            System.out.println(e);
                        }
                    }
                }
            }
        }
    }

  這里的 shareObject.notify();會從shareObject對象的等待隊列中隨機喚醒一個線程,但是目前的shareObject對象的等待隊列中只有ThreadOne一個線程,所以它就被喚醒了。

  過程如下圖:

  

    最后:wait和sleep區別

  

    1️⃣ wait和sleep方法都可以讓線程等待;


    2️⃣ wait()方法可以被喚醒,sleep不能被喚醒。


    3️⃣ wait()既會釋放cpu,也會釋放共享資源的鎖,sleep()不會釋放任何資源。


    4️⃣ wait和sleep方法都可以使線程進人阻塞狀態。


    5️⃣ wait和sleep方法均是可中斷方法,被中斷后都會收到中斷異常。


    6️⃣ wait是Object的方法,而sleep是Thread特有的方法。


    7️⃣ wait方法的執行必須在同步方法中進行,而sleep則不需要。


    8️⃣ 線程在同步方法中執行sleep方法時,並不會釋放monitor的鎖,而wait方法則會釋放monitor的鎖。


    9️⃣ sleep方法短暫休眠之后會主動退出阻塞,而wait方法(沒有指定wait時間)則需要被其他線程中斷后才能退出阻塞。

 

    🔟 sleep:是Thread的靜態方法,會使當前線程釋放cpu,但不會釋放鎖資源,可以理解為只和cpu有關,不涉及鎖資源。涉及鎖資源的,是wait,join方法。

 

    🔟1️⃣ yield:也是Thread的靜態方法,和sleep方法類似,會使當前線程釋放cpu,但不會釋放鎖資源。和sleep不同的是,sleep必須設置時間,但是yield不能設置時間,時間值是隨機的

 

    🔟2️⃣ join: 等待join方法執行線程先執行完畢, main方法再繼續執行; 例如 main方法中有一個線程thread執行了thread.join() ; 那么當main方法執行到了thread.join()語句時,必須等待thread線程執行完畢,才能繼續執行;thread必須執行了start方法才會這樣,如果沒有執行start方法main方法會直接執行下去.

 

    結束🔚


免責聲明!

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



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