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 * <i>interrupted status</i> 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方法,亦或者等待时间到达. * <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> * wait()方法使得调用这个方法的线程T将自己放在当前对象的等待集合中,并放弃了所有针对这个对象的同步操作声明.线程T不能在参与线程调度,并且一直处于休眠状态,直到下面四件事中的某一个发生为止: (1)其它线程调用了当前对象的notify方法,并且线程T刚刚好是那个被选中唤醒的线程. (2)其它线程调用了当前对象的notifyAll方法. (3)其它线程中断了线程T. (4)线程T的被指定的等待时间到达.然而,如果超时时间在一开始被指定为0,那么这种指定就是失效的,也就是线程并不能立即被使用,而是需要被其它线程唤醒才能使用. * 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. * 当线程T被唤醒后,它将从wait等待集合中删除,且继续可以参与线程调度了.此后,它会和其它线程一样去竞争对当前对象的同步操作;如果线程T获得了当前对象的控制权,那么线程T的同步声明都会被恢复到它之前调用wait方法时候的状态.然后线程T就从wait方法返回.因此,从wait方法返回,当前对象和线程T的同步状态都会被恢复为wait方法调用的时候(这一点很好理解:线程T调用wait方法,此时线程T的所有状态被保存;当线程T被唤醒并且被选中作为当前对象操作的线程,那么线程T在工作之前,必须先恢复它原来的状态,也就调用wait方法时的状态.). * <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). * 一个线程不被唤醒 or 不被中断 or 等待时间到达,也能自己醒来,这种醒来被称为"伪醒来".尽管这在实践中几乎不会出现,但是应用程序还是应该防范这一情况的出现,可以通过测试线程被唤醒的条件 and 什么条件下不能被唤醒,从而达到防御目的.换句话说,wait方法只能在循环中发生,比如下面这样: * synchronized (obj) { * while (condition does not hold) * obj.wait(timeout); * } * (关于这个问题的更多信息,可以查看Doug Lea的<java并发编程>章节3.2.3) * <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. * 如果当前线程在wait方法调用前或者正在wait时被其他线程中断,那么会抛出异常InterruptedException.注意这一异常的抛出时间是有规定的:这一时间必须是:当前Object被解锁,当前对象和线程T的同步状态都会被恢复为wait方法调用的时候. * <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. * 注意:由于wait方法是将当前线程放到了当前对象的wait集合里面,所以当wait方法结束时,解锁的也只是当前这个对象; * 当前线程用于同步的其他对象会保持线程调用wait方法时的锁状态.(关于这句话的理解,举个例子:线程如果因为m(m>1)个资源被阻塞,那么得到1个资源时,只是这个资源可以从wait状态恢复,其他的(m-1)个资源依旧是wait状态.因为当前线程的运行还需要其他(m-1)个资源,因此此时的线程还是不能够运行的.) * * <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. * 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 <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;
参考http://www.cnblogs.com/DreamSea/archive/2012/01/16/2263844.html