欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Object.wait()与Object.notify()的用法详细解析

程序员文章站 2023-12-20 17:32:04
wait、notify和notifyall方法是object类的final native方法。所以这些方法不能被子类重写,object类是所有类的超类,因此在程序中有以下三...

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()这样的语句写在当前上下文中。如:

复制代码 代码如下:

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)

正确的写法应该是
复制代码 代码如下:

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

上一篇:

下一篇: