【Java】Java中Wait、Sleep和Yield方法的区别

  • sleep()和yield()方法是定义在Thread类中,而wait()方法是定义在Object类中。
  • wait()是用于线程间通信,而sleep()是用于短时间暂停当前线程。更加明显的一个区别在于,当一个线程调用wait()方法的时候,会释放它锁持有的对象的管程和锁,但是调用sleep()方法的时候,不会释放它所持有的管程。
  • yield()方法与wait()和sleep()方法有一些区别,它仅仅释放线程所占有的CPU资源,从而让其他线程有机会运行,但是并不能保证某个特定的线程能够获得CPU资源。谁能获得CPU完全取决于调度器,在有些情况下调用yield方法的线程甚至会再次得到CPU资源。所以,依赖于yield方法是不可靠的,它只能尽力而为。
  • wait和sleep的主要区别是调用wait方法时,线程在等待的时候会释放掉它所获得的monitor,但是调用Thread.sleep()方法时,线程在等待的时候仍然会持有monitor或者锁。另外,Java中的wait方法应在同步代码块中调用,但是sleep方法不需要。
  • 另一个区别是Thread.sleep()方法是一个静态方法,作用在当前线程上;但是wait()方法是一个实例方法,并且只能在其他线程调用本实例的notify()方法时被唤醒。
  • 另外,使用sleep()方法时,被暂停的线程在被唤醒之后会立即进入就绪态(Runnable state),但是使用wait方法的时候,被暂停的线程会首先获得锁,即阻塞态,然后再进入就绪态,所以,根据你的需求,如果你需要暂定你的线程一段特定的时间就使用sleep()方法,如果你想要实现线程间通信就使用wait()方法。
    • wait只能在同步(synchronize)环境中被调用,而sleep不需要。
    • 进入wait状态的线程能够被notify和notifyAll线程唤醒,但是进入sleeping状态的线程不能被notify方法唤醒。
    • wait通常有条件地执行,线程会一直处于wait状态,直到某个条件变为真。但是sleep仅仅让你的线程进入睡眠状态。
    • wait方法在进入wait状态的时候会释放对象的锁,但是sleep方法不会。
    • wait方法是针对一个被同步代码块加锁的对象,而sleep是针对一个线程。
  • yield方法会临时暂停当前正在执行的线程,来让有同样优先级的正在等待的线程有机会执行。如果没有正在等待的线程,或者所有正在等待的线程的优先级都比较低,那么该线程会继续执行。执行了yield方法的线程什么时候会继续运行由线程调度器来决定,不同的厂商可能有不同的行为。yield方法不保证当前的线程会暂停或者停止,但是可以保证当前在调用yield方式时会放弃CPU。

sleep方法的几个注意点

  • Thread.sleep()方法用来暂停线程的执行,将CPU放给线程调度器
  • Thread.sleep()方法是一个静态方法,它暂停的是当前执行的线程
  • Java有两种sleep方法,一个只有一个毫秒参数,另一个有毫秒和纳秒两个参数
  • 与wait方法不同,sleep方法不会释放锁
  • 如果其他的线程中断了一个休眠的线程,sleep方法会抛出Interrupted Exception
  • 休眠的线程在唤醒之后不保证能获取到CPU,它会先进入就绪态,与其他线程竞争CPU
  • 有一个易错的地方,当调用t.sleep()的时候,会暂停线程t。这是不对的,因为Trhead.sleep是一个静态方法,它会使当前线程而不是线程t进入休眠状态。

你可能感兴趣的:(【Java】Java中Wait、Sleep和Yield方法的区别)