欢迎大家来到IT世界,在知识的湖畔探索吧!
wait、notify和notifyAll方法是Object类的final native方法,这些方法不能被子类重写,Object类是所有类的超类,所以每个类都有这三个方法。其中wait有三个重载方法。
void wait()
导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。这里wait与sleep方法不同,sleep方法只是停止当前进程,但是不会释放当前的锁,而wait会把当前的锁也释放。
void wait(long millis)
这里的参数是毫秒,也就是等待长达n毫秒,如果没有通知就超时返回。在等待时间过去后就直接重新获取锁,往后执行;但是在竞争条件下,都会等获取到锁了才可以往下执行
void wait(long millis,int nanos)
导致线程进入等待状态,对于等待时间更细粒度的控制,可以达到毫秒。在等待时间过去后就直接重新获取锁,往后执行;但是在竞争条件下,都会等获取到锁了才可以往下执行
void notify()
随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态。该方法只能在同步方法或同步块内部调用。
void notifyAll()
解除所有那些在该对象上调用wait方法的线程的阻塞状态。该方法只能在同步方法或同步块内部调用。
- 注意
由上面得出,Object.wait()和Object.notify()和Object.notifyall()必须写在synchronized方法内部或者synchronized块内部,这是因为:这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁。即使你确实知道当前上下文线程确实拥有了对象锁,也不能将object.wait()这样的语句写在当前上下文中。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
接下里我们写个demo用例测试一下:
package com.consumer.test;
public class WaitTest {
public static void main(String[] args) {
Object object = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程wait等待获取object锁");
synchronized (object) {
try {
System.out.println("线程wait获取了object锁");
// 会暂停进程但是不会释放锁
Thread.sleep(1000);
System.out.println("线程wait将要运行object.wait()方法进行等待");
object.wait();
System.out.println("线程wait得到通知。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程notify等待获取object锁");
synchronized (object) {
System.out.println("线程notify获取了object锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程notify将要运行object.notify()方法进行通知");
object.notify();
}
}
}).start();
}
}
欢迎大家来到IT世界,在知识的湖畔探索吧!
我们从运行结果中发现notify方法通知后,wait发放接到通知开始向下继续运行,对于wait的俩个重载和notifyAll方法就不一一叙述,有兴趣的可以自己去敲敲看。
如有错误请指出,谢谢。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/30335.html