<h2 id="sleep方法-vs-wait-方法">sleep()方法 VS wait() 方法
- 释放锁:
- 归属对象:
- Thread的static方法;
- Object的方法。
- 调用前后的影响:
- sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用,目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。
- 当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。wait()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。
-
源码: sleep()方法
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds,subject to
* the precision and accuracy of system timers and schedulers. The thread
* does not lose ownership of any monitors.
* @param millis
* the length of time to sleep in milliseconds
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* interrupted status of the current thread is
* cleared when this exception is thrown.
*/
public static native void sleep(long millis) throws InterruptedException;
wait()方法
/**
* 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.
* wait方法的调用会使得当前线程阻塞,直到其它的线程调用了对应对象的notify或者
* notifyAll方法,亦或者等待时间到达.
*
* The current thread must own this object's monitor.
* 当前线程必须拥有这个对象的监听器.
*
* This method causes the current thread (call it T) to
* place itself in the wait set for this object and then to relinquish
* any and all synchronization claims on this object. Thread T
* becomes disabled for thread scheduling purposes and lies dormant
* until one of four things happens:
*
* - Some other thread invokes the {@code notify} method for this
* object and thread T happens to be arbitrarily chosen as
* the thread to be awakened.
*
- Some other thread invokes the {@code notifyAll} method for this
* object.
*
- Some other thread {@linkplain Thread#interrupt() interrupts}
* thread T.
*
- 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.
*
* wait()方法使得调用这个方法的线程T将自己放在当前对象的等待集合中,并放弃了所有针对这个对象的同步操作声明.线程T不能在参与线程调度,并且一直处于休眠状态,直到下面四件事中的某一个发生为止:
(1)其它线程调用了当前对象的notify方法,并且线程T刚刚好是那个被选中唤醒的线程.
(2)其它线程调用了当前对象的notifyAll方法.
(3)其它线程中断了线程T.
(4)线程T的被指定的等待时间到达.然而,如果超时时间在一开始被指定为0,那么这种指定就是失效的,也就是线程并不能立即被使用,而是需要被其它线程唤醒才能使用.
* The thread T 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 T 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.
* 当线程T被唤醒后,它将从wait等待集合中删除,且继续可以参与线程调度了.此后,它会和其它线程一样去竞争对当前对象的同步操作;如果线程T获得了当前对象的控制权,那么线程T的同步声明都会被恢复到它之前调用wait方法时候的状态.然后线程T就从wait方法返回.因此,从wait方法返回,当前对象和线程T的同步状态都会被恢复为wait方法调用的时候(这一点很好理解:线程T调用wait方法,此时线程T的所有状态被保存;当线程T被唤醒并且被选中作为当前对象操作的线程,那么线程T在工作之前,必须先恢复它原来的状态,也就调用wait方法时的状态.).
*
* A thread can also wake up without being notified,interrupted,or
* timing out,a so-called spurious wakeup. 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:
*
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
*
* (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).
* 一个线程不被唤醒 or 不被中断 or 等待时间到达,也能自己醒来,这种醒来被称为"伪醒来".尽管这在实践中几乎不会出现,但是应用程序还是应该防范这一情况的出现,可以通过测试线程被唤醒的条件 and 什么条件下不能被唤醒,从而达到防御目的.换句话说,wait方法只能在循环中发生,比如下面这样:
* synchronized (obj) {
* while (condition does not hold)
* obj.wait(timeout);
* }
* (关于这个问题的更多信息,可以查看Doug Lea的章节3.2.3)
* 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.
* 如果当前线程在wait方法调用前或者正在wait时被其他线程中断,那么会抛出异常InterruptedException.注意这一异常的抛出时间是有规定的:这一时间必须是:当前Object被解锁,当前对象和线程T的同步状态都会被恢复为wait方法调用的时候.
*
* 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.
* 注意:由于wait方法是将当前线程放到了当前对象的wait集合里面,所以当wait方法结束时,解锁的也只是当前这个对象;
* 当前线程用于同步的其他对象会保持线程调用wait方法时的锁状态.(关于这句话的理解,举个例子:线程如果因为m(m>1)个资源被阻塞,那么得到1个资源时,只是这个资源可以从wait状态恢复,其他的(m-1)个资源依旧是wait状态.因为当前线程的运行还需要其他(m-1)个资源,因此此时的线程还是不能够运行的.)
*
*
* 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.
* wait方法只能被拥有对象的监听器的线程调用.关于成为一个对象的监听器的方法可以查看notify方法,里面写了3种方法.
* @param timeout the maximum time to wait in milliseconds. 等待时间的最长毫秒数.
* @exception IllegalArgumentException if the value of timeout is
* negative.
* @exception IllegalMonitorStateException if the current thread is not
* the owner of the object's monitor.
* @exception InterruptedException if any thread interrupted the
* current thread before or while the current thread
* was waiting for a notification. The interrupted
* status 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;
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|