开发者

Java中wait()和sleep()区别小结

目录
  • 1. 所属类与基本性质
  • 2. 锁的行为差异(核心区别)
  • 3. 使用场景
  • 4. 唤醒机制
  • 5. 调用前提条件
  • 6. 异常处理
  • 7. 线程状态变化
  • 代码示例对比
    • sleep() 示例(不释放锁)
    • wait() 示例(释放锁)
  • 总结对比表
    • 关键结论

      在php Java 多线程编程中,wait()sleep()是两个常用的线程控制方法,但它们在工作原理、使用场景和效果上有显著区别。以下是两者的主要差异:

      1. 所属类与基本性质

      • sleep()​​:是 Thread类的静态方法,可以直接通过 Thread.sleep()调用,用于让当前线程暂停执行指定的时间。
      • wait()​​:是 Object类的实例方法,必须通过对象实例调用(如 obj.wait()),主要用于线程间的通信与协调。

      2. 锁的行为差异(核心区别)

      • sleep()​​:

        • 不释放锁​:当线程调用 sleep()时,即使线程进入休眠状态,它仍然持有已经获取的任何对象锁。
        • 其他线程无法获取被休眠线程持有的锁,导致同步代码块或方法无法被并发执行。
      • wait()​​:

        • 释放锁​:调用 wait()会使线程释放当前持有的对象锁,并进入该对象的等待池(waiting pool)。
        • 其他线程可以获取该对象的锁并执行同步代码。

      3. 使用场景

      • sleep()​​:

        • 用于让线程暂停执行一段时间,不涉及线程间通信。
        • 典型场景:模拟延迟、定时任务、控制执行节奏等。
      • wait()​​:

        • 用于线程间协作,通常与 notify()/notifyAll()配合使用。
        • 典型场景:生产者-消费者模式、线程交替执行等需要条件等待的场景。

      4. 唤醒机制

      • sleep()​​:

        • 自动唤醒:线程会在指定的时间结束后自动恢复就绪状态。
      • wait()​​:

        • 需要被动唤醒:必须由其他线程调用同一对象的 notify()notifyAll()方法才能唤醒。
        • 也支持带超时的 wait(long timeout),超时后会自动唤醒。

      5. 调用前提条件

      • sleep()​​:

        • 可以在任何地方调用,不需要在同步代码块中。
      • wait()​​:

        • 必须在同步代码块或同步方法中调javascript​(即必须先获取对象的监视器锁)。
        • 否则会抛出 IllegalMonitorStateException异常。

      6. 异常处理

      两者都会抛出 InterruptedException

      • 当线程在休眠或等待期间被其他线程中断时触发。
      • 都需要捕获或声明抛出该异常。

      7. 线程状态变化

      • sleep()​​:

        • 使线程进入 ​TIMED_WAITING​(带超时)或 ​WAITING​(无超时)状态。
      • wait()​​:

        • 使线程进入 ​WAITING​(无超时)或 ​TIMED_WAITING​(带超时)状态,并释放锁。

      代码示例对比

      sleep() 示例(不释放锁)

      synchronized (lock) {
          System.out.println("线程获取锁,开始sleep");
          try {
              Thread.sleep(2000); // 休眠2秒,不释放lock锁
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("线程sleep结束");
      }
      // 其他线程必须等待sleep结束后才能获取锁
      

      wait() 示例(释放锁)

      synchronized (lock) {
          System.out.println("线程获取锁,开始wait");
          try {
              lock.wait(); // 释放lock锁,进入等待队列
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("线程被唤醒,重新获取锁");
      }
      // 其他线程可以在wait期间获取lock锁
      

      总结对比表

      特性sleep()wait()
      所属类Thread类的静态方法Object类的实例方法
      锁释放不释放锁释放锁
      使用场景线程暂停执行线程间通信与协作
      唤醒方式自动唤醒(时间到)notify()/notifyAll()唤醒
      调用前提无需同步环境必须在 编程客栈synchronized中调用
      异常InterruptedExceptionInterruptedException+ IllegalMonitorStateExcepti编程客栈on
      典型用途定时、延迟生产者-消费者、条件等待

      关键结论

      1. 锁行为​:sleep()持有锁不放,wait()释放锁——这是最本质的区别。
      2. 协作机制​:wait()/notify()是 Java 多线程协作的基础机制,而 sleep()只是单纯的线程暂停。
      3. 使用规范​:误用 wait()(如不在同步块中调用)会导致运行时异常,而 sleep()的使用相对简单。

      在实际开发中,应根据是否需要线程间协作来选择使用哪个方法:若只是需要延迟,用 sleep();若需要等待某个条件满足(如资源就绪),则用 wait()

      到此这篇编程关于Java中wait()和sleep()区别小结的文章就介绍到这了,更多相关Java wait()和sleep()区别内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜