当前位置: 移动技术网 > IT编程>开发语言>Java > Object.wait()与Object.notify()的用法详细解析

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网