2018-05-15 線程通信(wait和notify方法)

(注意) t1.wait(); // 不是使t1線程等待,而是讓擁有t1這個(gè)對(duì)象的主線程等待

package test;
 
public class WaitTest2 { 
    public static void main(String[] args) {  
       ThreadA t1 = new ThreadA("t1"); 
        synchronized(t1) {  
            try {  
                // 啟動(dòng)“線程t1”  
                System.out.println(Thread.currentThread().getName()+" start t1");  
                t1.start();  
                // 主線程等待t1通過notify()喚醒。  
                System.out.println("掛起主線程"); 
                System.out.println("線程t1的狀態(tài)是:"+t1.isAlive());
                t1.wait();  //  不是使t1線程等待,而是讓擁有t1這個(gè)對(duì)象的主線程等待
                System.out.println("掛起主線程后面的輸出");  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        } 
 
    }  
} 
class ThreadA extends Thread{  
    public ThreadA(String name) {  
        super(name);  
    }  
    public void run() {  
        synchronized (this) {  
            try {                         
                Thread.sleep(1000); //  使當(dāng)前線阻塞 1 s確保在主線程wait()之前t1沒有執(zhí)行完并退出 
            } catch (Exception e) {  
                e.printStackTrace();  
            }             
            //System.out.println(Thread.currentThread().getName()+" call notify()");  
            // 喚醒當(dāng)前的wait線程  
            //this.notify();  
        }  
    }  
}

main start t1
掛起主線程
線程t1的狀態(tài)是:true
掛起主線程后面的輸出

在上面的例子中,同樣是把notify()這個(gè)方法注釋掉了,但是主線程wait()后面的代碼還是可以得到執(zhí)行,這說明了t1.wait()運(yùn)行后,不需要t1.notify()能夠喚醒!

線程正常結(jié)束后,會(huì)使以這個(gè)線程對(duì)象運(yùn)行的wait()等待,退出等待狀態(tài)!而如果在運(yùn)行wait()之前,線程已經(jīng)結(jié)束了,則這個(gè)wait就沒有程序喚醒了,例如如果上述不睡1秒的話,在主線程的t1.wait()執(zhí)行之前就運(yùn)行完畢退出那么主線程就無法被喚醒了。

實(shí)際上,Thread源碼里面的join()方法也是使用這種機(jī)制:

原碼里的join()方法,實(shí)際上就是運(yùn)行的 wait(). 需要運(yùn)行join的線程運(yùn)行join方法,實(shí)際上是在此線程上調(diào)用了需要加入的線程對(duì)象的wait()方法,加入的線程運(yùn)行完后,自然從wait退出了。

結(jié)論:

線程對(duì)象的wait()方法運(yùn)行后,可以不用其notify()方法退出,會(huì)在線程結(jié)束后,自動(dòng)退出。


線程通信.JPG
while(true) {
        synchronized (r) {
        
          if(!r.flag) {
              try {
                r.wait(); //雖然wait()是object的方法,任何它的子類都可以調(diào)用,但是此處還是要 用 共有資源的對(duì)象來調(diào)用
            } catch (Exception e) {
                
            }
          }
            System.out.println(r.name+""+r.sex+"");
            r.flag=true;
            r.notify();}
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容