Java 中 Wait,Sleep 和 Yield 的区别

Java 中 wait 和 sleep 之间的区别或者 sleep 和 yield 之间的区别是流行的核心 Java 面试问题之一,并且在多线程面试中被问到。 在 Java 中可用于暂停线程的三种方法中,sleep() 和 yield() 方法定义在线程类中,而 wait() 方法定义在 Object 类中,这是另一个面试问题。 wait() 和 sleep() 之间的主要区别在于前者用于线程间通信,而后者用于引入以暂停当前线程一小段时间。

这种区别在以下事实中更加明显:当一个线程调用 wait() 方法时,它会释放它持有的监视器或锁定该对象,但是当一个线程调用 sleep() 方法时,它甚至不会释放监视器 如果它持有。

回到 yield(),它与 wait() 和 sleep() 没什么不同,它只是释放线程占用的 CPU,让另一个线程有机会运行,但不能保证谁会获得 CPU。

这完全取决于线程调度程序,调用 yield() 方法的线程甚至有可能再次获得 CPU。 因此,依赖 yield() 方法是不可靠的,它只是在尽力而为的基础上。


Java 中 Wait vs Sleep vs Yield

在本 Java 文章中,我们将了解什么是 Java 中的 sleep 、Java 中 sleep 的要点以及 Java 中 Wait 和 sleep 的区别。

Java Wait和 Sleep 的区别

Java示例中 sleepwait 和 yield 的区别 wait 和 sleep 的主要区别是wait()方法在线程等待时释放获取的监视器,而 Thread.sleep() 方法保持锁或监视器,即使线程正在等待。 另外,Java 中的 wait 方法应该从同步方法或块中调用,而 sleep() 方法没有这样的要求。

另一个区别是 Thread.sleep() 方法是一个静态方法,适用于当前线程,而 wait() 是一个特定于实例的方法,只有在其他线程调用同一对象上的 notify 方法时才会被唤醒。

同样,在 sleep 的情况下,休眠的线程被唤醒后立即进入 Runnable 状态,而在 wait 的情况下,等待线程先获取锁,然后进入 Runnable 状态。 所以根据你的需要,如果你想暂停一个线程指定的时间那么使用sleep()方法,如果你想实现线程间通信使用wait方法。

以下是 Java 中 wait 和 sleep 之间的区别列表:

  1. wait 只能从同步上下文中调用,而 sleep 可以在没有同步块的情况下调用。 有关更多详细信息,请参阅为什么 wait,notify 和 notifyall 需要从同步方法调用。
  2. 等待线程可以通过调用notifynotifyAll唤醒,而休眠线程不能通过调用notify方法唤醒。
  3. 等待通常在条件下完成,线程等待直到条件为真,而睡眠只是让你的线程进入睡眠状态。
  4. 在等待睡眠时等待对象上的释放锁不会在等待时释放。
  5. wait()方法在同步块被锁定的对象上调用,而 sleep() 在 Thread 上调用。

Java 中 yield 和 sleep 的区别

Java 中 yield 和 sleep 之间的主要区别在于 yield() 方法暂时暂停当前正在执行的线程,以便为具有相同优先级的其余等待线程提供执行的机会。 如果没有等待线程或所有等待线程的优先级都较低,则同一线程将继续执行。

产生的线程何时有机会执行由线程调度程序决定,线程调度程序的行为取决于供应商。 yield 方法不保证当前线程将暂停或停止,但它保证 CPU 将由于调用 java 中的 Thread.yield() 方法而被当前线程放弃。

Java 中的睡眠方法有两种变体,一种以毫秒为休眠时间,另一种以毫秒和纳秒为休眠持续时间。

sleep(long millis)

或者

sleep(long millis,int nanos)

使当前执行的线程休眠指定的毫秒数加上指定的纳秒数。

这是一个很好的图表,它显示了线程转换如何通过调用 wait() 、sleep() 和 yield() 方法发生在不同的线程状态。


Java 中的 Thread.sleep() 方法示例

这是 Java 中 Sleep Thread 的示例代码示例。 在此示例中,我们已将主线程置于睡眠状态 1 秒。

/*
 * Example of Thread Sleep method in Java
 */
public class SleepTest {
      
       public static void main(String... args){
              System.out.println(Thread.currentThread().getName() + " is going to sleep for 1 Second");
              try {
                     Thread.currentThread().sleep(1000);
              } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              }
              System.out.println("Main Thread is woken now");
       }

}

关于Java中Thread sleep()方法的几点说明

我列出了一些重要且值得记住的关于 Java 中 Thread 类的 Sleep() 方法的要点:

  1. Thread.sleep()方法用于暂停执行,让出CPU返回给线程调度器。
  2. Thread.sleep()方法是静态方法,总是让当前线程进入睡眠状态。
  3. Java在Thread类中有两种睡眠方法变体,一种是一个参数,以毫秒为睡眠持续时间,另一种方法有两个参数,一个是毫秒,另一个是纳秒。
  4. 与Java 中的 wait() 方法不同,Thread 类的 sleep() 方法不会放弃它已获得的锁。
  5. 如果另一个线程中断了 java 中的睡眠线程,则 sleep() 方法会抛出中断异常。
  6. Java中的 sleep() 不能保证休眠线程醒来时一定会得到CPU,而是进入 Runnable 状态与其他线程争夺CPU。
  7. Java 中对睡眠方法存在一种误解,认为调用 t.sleep() 会将线程“t”置于睡眠状态,这是不正确的,因为 Thread.sleep 方法是静态方法,它总是将当前线程置于睡眠状态,并且 不是线程“t”。

这就是 Java 中的 Sleep 方法。 我们已经看到了 sleep 和 wait 之间的区别以及 Java 中的 sleep 和 yield 。 总之,请记住 sleep() 和 yield() 都在当前线程上运行。