2019独角兽企业重金招聘Python工程师标准>>>
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's monitor. If any threads are waiting on this object, one of them is 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 (<condition does not hold>)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, or some 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 blocke.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 blocke.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 {@Overridepublic void run() {// 加锁 拥有lock 的 monitorsynchronized (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 {@Overridepublic 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方法的用法。
参考:http://www.cnblogs.com/xwdreamer/archive/2012/05/12/2496843.html
后记:Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
==============END==============