wait() vs sleep() 在 Java 中:为线程选择哪一个?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

wait() vs sleep() 在 Java 中:多线程的巅峰对决

\n\n

想象一下,您是一位乐队指挥。您有小提琴手(线程),他们需要协调演奏,但有时他们需要等待其他人完成他们的部分。在 Java 中,有两种强大的工具可以管理此类暂停:wait() 和 sleep()。乍一看,它们很相似——两者都会使线程“暂停”一段时间。但实际上,它们是完全不同的机制,混淆它们肯定会造成死锁或竞态条件。

\n\n

本文是您穿越多线程丛林指南。我们不仅会列出区别,还会通过生动的示例进行剖析,让您永远记住:sleep 是暂停,而 wait 是释放资源。开始吧!

\n\n

什么是 sleep()?(Thread.sleep)

\n\n

Thread.sleep(毫秒) 方法是将当前线程“休眠”指定时间的最简单方法。线程只是休息,不会释放对象的锁。它就像一只懒惰的猫,在沙发上打盹,但仍然用爪子抓着玩具。

\n\n

关于 sleep() 的重要事实:

\n
    \n
  • 它是 Thread 类的静态方法。
  • \n
  • 线程不会释放它持有的监视器(锁)。
  • \n
  • 计时器到期后,线程进入 Runnable(可运行)状态。
  • \n
  • 可能抛出 InterruptedException。
  • \n
\n\n

简单示例:

\n
public class SleepExample {\n    public static void main(String[] args) throws InterruptedException {\n        System.out.println("开始: " + System.currentTimeMillis());\n        Thread.sleep(2000); // 休眠 2 秒\n        System.out.println("醒来: " + System.currentTimeMillis());\n    }\n}
\n\n

结果:两次输出之间恰好间隔 2 秒。线程只是等待,什么也不做。

\n\n

什么是 wait()?(Object.wait)

\n\n

wait() 方法不仅仅是一个暂停,而是一种线程间通信机制。它定义在 Object 类中,并且只能在同步块(synchronized)内调用。当线程调用 wait() 时,它会:

\n
    \n
  • 释放对象的监视器(即释放锁)。
  • \n
  • 进入 WAITING 或 TIMED_WAITING 状态(如果指定了超时时间)。
  • \n
  • 等待,直到另一个线程在同一个对象上调用 notify() 或 notifyAll()。
  • \n
\n\n

这就像您说:“我放下叉子,等待第二道菜上桌。”您不仅仅是睡觉——您是在为其他人腾出桌边的位置。

\n\n

基本示例:

\n
public class WaitNotifyExample {\n    private static final Object lock = new Object();\n\n    public static void main(String[] args) throws InterruptedException {\n        Thread waiter = new Thread(() -> {\n            synchronized (lock) {\n                try {\n                    System.out.println("服务员线程正在等待...");\n                    lock.wait(); // 释放 lock 并等待\n                    System.out.println("服务员线程收到通知!");\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n            }\n        });\n\n        Thread notifier = new Thread(() -> {\n            synchronized (lock) {\n                System.out.println("厨师线程正在准备...");\n                try {\n                    Thread.sleep(1000); // 模拟烹饪\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n                lock.notify(); // 唤醒等待的线程\n                System.out.println("厨师已通知服务员!");\n            }\n        });\n\n        waite                

博客

书籍推荐