Java多线程学习系列

"4-线程的睡眠&等待&让步&唤醒"

Posted by Dunno on January 24, 2016

线程的睡眠&等待&让步&唤醒

  • yield()
    • 发送请求告诉调度器“当前线程”让出当前对处理器资源的占用。调度器可以忽略该请求。
    • 很少场景会使用到这个方法,该方法可能对于debug或者出于测试的目的的场景有些用处(就是没有什么卵用的意思)。
    • D大调
  • sleep(long millis)
    • 当前的执行线程(注意是当前执行线程,比如如果你万一使用t1.sleep(1000),也不建议这么写,不一定会对t1起作用)进入休眠(暂停执行)。
    • 使用该方法时并不会让出对象的监视器。
  • wait(long timeout)
    • 使“当前线程”等待直到其他线程调用了notify()或者notifyAll()方法。
    • “当前线程”必须是此时正在起作用的对象监视器的所有者。
    • 该方法让“当前线程(以下用T表示)”等待同时释放对象监视器的锁,而且T在等待期间也不会再进行线程调度。除非发生以下一种情况:
      • 其他线程调用notify()时,随机唤醒了T线程。
      • 其他线程调用了notifyAll()
      • 其他线程interrupts了T线程
      • 指定的真实等待时间结束。当蚕食timeout是0时,那么则不会考虑timeout,线程T会一直等待直到被唤醒。
    • 线程可能不在上面四种情况下被唤醒,我们称为“spurious wakeup”,在实际操作中几乎不会发生。
  • wait()
    • wait()的实现是wait(0);
  • notify()
    • 唤醒一个在该对象监视器上等待的单个线程。
    • 唤醒的机制是随机唤醒。
    • 一次wait方法只能使一个线程在该对象监视器等待。
    • 被唤醒的线程不会开始处理程序直到当前线程释放了对这个对象监视器的锁。
    • 这个方法应该被这个对象监视器的拥有者的这个线程调用。一个线程成为对象监视器的拥有者有以下三个方法:
      • 通过执行一个这个对象的同步实例方法
      • 通过执行锁住这个对象的同步块方法
      • 对于Class类型的对象来说,通过执行这个类的一个静态的同步方法。
    • 一个线程在一个时刻只能拥有一个对象监视器。
  • notifyAll()
    • 唤醒在此对象监视器上面的所有等待的线程。