java wait until_Java wait && notify

Java wait && notify

‍wait、notify和notifyAll方法是Object类的final native方法,所以这些方法不能被子类重写。

方法 notifyAll()

Wakes up all threads that are waiting on this object's monitor.A thread waits on an object's monitor by calling one of the{wait} methods.

该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

方法 notify()

Wakes up a single thread that is waiting on this object'smonitor. If any threads are waiting on this object, one of themis chosen to be awakened.The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the {wait} methods.

该方法只能在同步方法或同步块内部调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

方法 wait()

Causes the current thread to wait until another thread invokes the{java.lang.Object#notify()} method or the{java.lang.Object#notifyAll()} method for this object.The current thread must own this object's monitor.

调用该方法的线程进入WAITING 状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait方法后,才会释放对象的锁。

该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。下面是一个wait的示例

synchronized (object) {

while ()

object.wait();

// ...

}

方法 wait(long millis)&&wait(long millis,int nanos)

Causes the current thread to wait until another thread invokes the { java.lang.Object#notify()} method or the{java.lang.Object#notifyAll()} method for this object, orsome other thread interrupts the current thread, or a certain amount of real time has elapsed(消逝,过去).

超时等待一段时间后,这里的参数时间是毫秒,也就是等待长达n毫秒,如果没有通知就超时返回。

这些方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。

timeout -- 最大的等待时间(以毫秒为单位)。

nanos   -- 额外的时间,在纳秒范围为0-999999。

‍Object.wait()和Object.notify()和Object.notifyAll()必须写在synchronized方法内部或者synchronized块内部,这是因为:这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁(内置锁)。即使你确实知道当前上下文线程确实拥有了对象锁,也不能将object.wait()这样的语句写在当前上下文中。‍

下面这段代码的写法是错误的。

package sync;

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

}

}

}

应该要这么写:

package sync;

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

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

Thread t = Thread.currentThread();

System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());

}

}

完整示例,

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.concurrent.TimeUnit;

public class WaitNotifyDemo {

static boolean flag = true;

static Object lock = new Object();

public static void main(String[] args) throws InterruptedException {

Thread waitThread = new Thread(new Wait(), "waitThread");

waitThread.start();

TimeUnit.SECONDS.sleep(1);

Thread notifyThread = new Thread(new Notify(), "notifyThread");

notifyThread.start();

}

static class Wait implements Runnable {

@Override

public void run() {

// 加锁 拥有lock 的 monitor

synchronized (lock) {

while (flag) {

try {

System.out.println(Thread.currentThread() + " flag is true. wait @ " +

new SimpleDateFormat("HH:mm:ss").format(new Date()));

// 释放了对象的监视器锁

lock.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread() + " flag is false. running @ " +

new SimpleDateFormat("HH:mm:ss").format(new Date()));

}

}

}

static class Notify implements Runnable {

@Override

public void run() {

synchronized (lock) {

System.out.println(Thread.currentThread() + " hold lock. notify @ " +

new SimpleDateFormat("HH:mm:ss").format(new Date()));

lock.notifyAll();

flag = false;

try {

Thread.sleep(1000 * 5);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

以上就是关于wait和notify方法的用法。

后记:Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

==============END==============

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值