Object.wait()與Object.notify()的用法


參考文獻:

object.wait()和object.notify()和object.notifyall()

正文

wait、notify和notifyAll方法是Object類的final native方法。所以這些方法不能被子類重寫,Object類是所有類的超類,因此在程序中有以下三種形式調用wait等方法。

wait();//方式1:
this.wait();//方式2:
super.wait();//方式3

void notifyAll()

解除所有那些在該對象上調用wait方法的線程的阻塞狀態。該方法只能在同步方法同步塊內部調用。如果當前線程不是鎖的持有者,該方法拋出一個IllegalMonitorStateException異常。

void notify()

隨機選擇一個在該對象上調用wait方法的線程,解除其阻塞狀態。該方法只能在同步方法同步塊內部調用。如果當前線程不是鎖的持有者,該方法拋出一個IllegalMonitorStateException異常。

void wait()

導致線程進入等待狀態,直到它被其他線程通過notify()或者notifyAll喚醒。該方法只能在同步方法中調用。如果當前線程不是鎖的持有者,該方法拋出一個IllegalMonitorStateException異常。

void wait(long millis)和void wait(long millis,int nanos)

導致線程進入等待狀態直到它被通知或者經過指定的時間。這些方法只能在同步方法中調用。如果當前線程不是鎖的持有者,該方法拋出一個IllegalMonitorStateException異常。

Object.wait()和Object.notify()和Object.notifyall()必須寫在synchronized方法內部或者synchronized塊內部,這是因為:這幾個方法要求當前正在運行object.wait()方法的線程擁有object的對象鎖。即使你確實知道當前上下文線程確實擁有了對象鎖,也不能將object.wait()這樣的語句寫在當前上下文中。如: 

View Code
package edu.sjtu.erplab.ObjectTest;

class A
{
    public synchronized void printThreadInfo() throws InterruptedException
    {
        Thread t=Thread.currentThread();
        System.out.println("ThreadID:"+t.getId()+", ThreadName:"+t.getName());
    }
}



public class ObjectWaitTest {
    public static void main(String args[])
    {
        A a=new A();
        //因為printThreadInfo()方法拋出InterruptedException異常,所以這里必須使用try-catch塊
        try {
            a.printThreadInfo();
            a.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}

程序運行會報錯,運行結果如下:

ThreadID:1, ThreadName:main
Exception in thread "main" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at edu.sjtu.erplab.ObjectTest.ObjectWaitTest.main(ObjectWaitTest.java:24)

正確的寫法應該是

View Code
package edu.sjtu.erplab.ObjectTest;

class A
{
    public synchronized void printThreadInfo() throws InterruptedException
    {
        Thread t=Thread.currentThread();
        System.out.println("ThreadID:"+t.getId()+", ThreadName:"+t.getName());
//        this.wait();//一直等待
        this.wait(1000);//等待1000ms
//        super.wait(1000);
    }
}



public class ObjectWaitTest {
    public static void main(String args[])
    {
        A a=new A();
        //因為printThreadInfo()方法拋出InterruptedException異常,所以這里必須使用try-catch塊
        try {
            a.printThreadInfo();
            //a.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        Thread t=Thread.currentThread();
        System.out.println("ThreadID:"+t.getId()+", ThreadName:"+t.getName());
    }
}

具體的可以參考多線程開發中提到的消費者與生產者案例的最后一個代碼示例。

 


免責聲明!

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



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