加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

sleep()方法和wait()方法的比较

发布时间:2020-12-14 06:39:28 所属栏目:Java 来源:网络整理
导读:h2 id="sleep方法-vs-wait-方法"sleep()方法 VS wait() 方法 释放锁: 不释放; 释放。 归属对象: Thread的static方法; Object的方法。 调用前后的影响: sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用,目的是不让当前线程独自霸占该进程

<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 (&lt;condition does not hold&gt;)
    *             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;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读