Java 中 sleep() 和 wait() 之间的区别

本文旨在探讨 Java 中 sleep()wait() 方法之间的区别,分析何时使用哪种方法,以及它们对 Java 并发编程带来的影响。

1. 核心机制讨论

sleep() 是一种用于暂停当前线程执行的方法,可以使线程暂停指定的毫秒数。而在使用 wait() 方法的情况下,线程会进入等待状态,直到其他线程调用该对象的 notify()notifyAll() 方法,它才会被唤醒并重新竞争锁。

两者的主要区别在于锁的处理机制:sleep() 不会释放锁(监视器),而 wait() 会释放锁。 wait() 通常用于线程间通信,而 sleep() 通常用于引入执行暂停或延时。

Thread.sleep() 会将当前线程发送到 TIMED_WAITING 状态一段时间。该线程会保留已获取的监视器,即如果该线程当前在某个 synchronized 块或方法中,则没有其他线程可以进入该块或方法。如果另一个线程调用 t.interrupt(),它将唤醒睡眠中的线程并抛出 InterruptedException

需要注意的是,sleep() 是一个 静态方法,这意味着它始终会影响当前线程(正在执行 sleep 方法的线程)。一个常见的错误是调用 t.sleep(),其中 t 是另一个线程对象。即使这样写,当前线程也会进入休眠状态,而不是线程 t

推荐阅读:使用 wait()notify()

2. 代码示例

sleep() 示例

synchronized 块中调用 sleep(),锁不会被释放:

synchronized(LOCK) {   
    Thread.sleep(1000); // LOCK 依然被当前线程持有
}

wait() 示例

synchronized 块中调用 wait(),锁会被释放:

synchronized(LOCK) {   
    LOCK.wait(); // LOCK 被释放,直到被唤醒并重新获取锁
}
推荐阅读yield()join() 之间的区别

3. 对比总结

简而言之,我们将以上要点进行分类总结,以便记忆和理解。

特性sleep()wait()
调用对象调用 Thread 类(静态方法);始终影响当前正在执行的线程。调用 Object 类;当前线程必须在锁对象上同步。
同步要求不需要同步上下文,但在同步块中使用时会持有锁。必须在 synchronized 同步块或方法中调用,否则抛出 IllegalMonitorStateException
锁行为不释放锁。休眠期间,其他线程无法进入同一对象的同步块。释放锁。允许其他线程有机会执行同步代码。
唤醒条件直到指定时间到期,或调用 interrupt() 中断。直到其他线程调用对象的 notify()notifyAll()
主要用途用于时间同步、暂停执行或模拟延时。用于多线程间的协作与通信。

希望以上信息能为您的知识库增加价值。

学习愉快!