/**
* Causes the current thread to wait until either another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or a
* specified amount of time has elapsed.
* <p>
* The current thread must own this object's monitor.
* <p>
* This method causes the current thread (call it <var>T</var>) to
* place itself in the wait set for this object and then to relinquish
* any and all synchronization claims on this object. Thread <var>T</var>
* becomes disabled for thread scheduling purposes and lies dormant
* until one of four things happens:
* <ul>
* <li>Some other thread invokes the {@code notify} method for this
* object and thread <var>T</var> happens to be arbitrarily chosen as
* the thread to be awakened.
* <li>Some other thread invokes the {@code notifyAll} method for this
* object.
* <li>Some other thread {@linkplain Thread#interrupt() interrupts}
* thread <var>T</var>.
* <li>The specified amount of real time has elapsed, more or less. If
* {@code timeout} is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified.
* </ul>
* The thread <var>T</var> is then removed from the wait set for this
* object and re-enabled for thread scheduling. It then competes in the
* usual manner with other threads for the right to synchronize on the
* object; once it has gained control of the object, all its
* synchronization claims on the object are restored to the status quo
* ante - that is, to the situation as of the time that the {@code wait}
* method was invoked. Thread <var>T</var> then returns from the
* invocation of the {@code wait} method. Thus, on return from the
* {@code wait} method, the synchronization state of the object and of
* thread {@code T} is exactly as it was when the {@code wait} method
* was invoked.
* <p>
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious wakeup</i>. While this will rarely
* occur in practice, applications must guard against it by testing for
* the condition that should have caused the thread to be awakened, and
* continuing to wait if the condition is not satisfied. In other words,
* waits should always occur in loops, like this one:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
* (For more information on this topic, see Section 3.2.3 in Doug Lea's
* "Concurrent Programming in Java (Second Edition)" (Addison-Wesley,
* 2000), or Item 50 in Joshua Bloch's "Effective Java Programming
* Language Guide" (Addison-Wesley, 2001).
*
* <p>If the current thread is {@linkplain java.lang.Thread#interrupt()
* interrupted} by any thread before or while it is waiting, then an
* {@code InterruptedException} is thrown. This exception is not
* thrown until the lock status of this object has been restored as
* described above.
*
* <p>
* Note that the {@code wait} method, as it places the current thread
* into the wait set for this object, unlocks only this object; any
* other objects on which the current thread may be synchronized remain
* locked while the thread waits.
* <p>
* This method should only be called by a thread that is the owner
* of this object's monitor. See the {@code notify} method for a
* description of the ways in which a thread can become the owner of
* a monitor.
*
* @param timeout the maximum time to wait in milliseconds.
* @throws IllegalArgumentException if the value of timeout is
* negative.
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
* @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final native void wait(long timeout) throws InterruptedException;
/**
* 使本线程(线程A)等待直到有另一个线(线程B)程调用同一个object
* {@link java.lang.Object#notify()} 方法或者
* {@link java.lang.Object#notifyAll()} 方法, 或者等了{@code timeout}这么久
* <p>
* 本线程(线程A)必须拥有这个object的monitor
* <p>
* 这个方法造成线程A进入object的等待队列并且闲置monitor
* 导致下一个堵塞于object的线程能够运行.
* 线程A将一直休眠,直到下面四个条件之一发生
* <ul>
* <li>1、有其他的线程执行了object的 {@code notify} 方法
* 并且线程A刚好被选中唤醒(notify只能唤醒一个等待的线程)
* <li>2、有其他线程执行了object的 {@code notifyAll} 方法
* <li>3、线程A执行{@linkplain Thread#interrupt() interrupts}
* <li>4、过了{@code timeout}的时长,如果{@code timeout}为0,那么会一直等到被唤醒
* </ul>
* 上述条件之一发生后,线程A将从等待队列出来,并且进入同步队列处于堵塞
* (关于什么是等待队列和同步序列,请看对象锁的原理)
* 当堵塞竞争结束,线程重新运行,object的synchronization claims恢复, 即线程A将在被
* 调用{@code wait}语句的地方重新执行,所以,恢复线程之后的object的
* synchronization state将和等待的时候一样。
* <p>
* 线程可以通过不用notify方法被唤醒,比如interrupted、timing out, 我们称这种异常
* 唤醒方式为<i>spurious wakeup</i>. 然而spurious wakeup实际经常发生,程序
* 一定要大量测试杜绝这种情况,直到满足条件才唤醒。因此,我们推荐以下模板:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
* (更多信息请查阅Section 3.2.3 in Doug Lea's
* "Concurrent Programming in Java (Second Edition)" (Addison-Wesley,
* 2000), 或者 Item 50 in Joshua Bloch's "Effective Java Programming
* Language Guide" (Addison-Wesley, 2001).
*
* <p>如果等待的线程被 {@linkplain java.lang.Thread#interrupt()
* interrupted},将会排除一个{@code InterruptedException}异常. 这个线程
* 会直到object的synchronization state恢复才排除
*
* <p>
* 注意 {@code wait} 会将本线程进入等待序列,并且释放object monitor,所以其他
* 堵塞于object monirotr的线程可以获取monitor
* <p>
* wait方法只能被拥有monitor的线程使用, {@code notify} 介绍了线程怎么获取monitor
*
* @param timeout the maximum time to wait in milliseconds.
* @throws IllegalArgumentException if the value of timeout is
* negative.
* @throws IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
* @throws InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when
* this exception is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final native void wait(long timeout) throws InterruptedException;