导读:本期聚焦于小伙伴创作的《Java里wait和sleep有什么区别?Java线程状态变化是怎样的》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java里wait和sleep有什么区别?Java线程状态变化是怎样的》有用,将其分享出去将是对创作者最好的鼓励。

在Java多线程编程中,wait和sleep都能让线程进入等待状态,但两者的底层实现、使用规则和线程状态变化逻辑存在明显差异,理解这些差异是写出正确多线程代码的基础。

Java里wait和sleep有什么区别?Java线程状态变化是怎样的

wait和sleep的核心区别

我们可以从多个维度对比这两个方法的差异,具体如下表所示:

对比维度wait方法sleep方法
所属类Object类的方法Thread类的静态方法
锁释放规则调用后会释放当前持有的对象锁调用后不会释放任何锁
使用前提必须在同步代码块或同步方法中调用,且要获取对应对象的锁可以在任意位置调用,无锁要求
唤醒方式依赖其他线程调用同一对象的notify或notifyAll方法,或者等待超时等待指定时间后自动唤醒,或者被中断唤醒
线程状态变化从RUNNABLE变为WAITING或TIMED_WAITING从RUNNABLE变为TIMED_WAITING

代码示例对比

下面通过两段代码分别展示wait和sleep的使用场景:

wait方法使用示例

public class WaitDemo {
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程1获取到锁,开始执行");
                try {
                    // 调用wait释放锁,进入等待状态
                    lock.wait(2000);
                    System.out.println("线程1被唤醒,继续执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程2获取到锁,开始执行");
                // 唤醒等待在lock对象上的线程
                lock.notify();
                System.out.println("线程2调用notify唤醒其他线程");
            }
        });

        thread1.start();
        // 让线程1先执行
        Thread.sleep(100);
        thread2.start();
    }
}

sleep方法使用示例

public class SleepDemo {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程1获取到锁,开始执行");
                try {
                    // 调用sleep不会释放锁
                    Thread.sleep(2000);
                    System.out.println("线程1睡眠结束,继续执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            // 等待线程1释放锁才能获取
            synchronized (lock) {
                System.out.println("线程2获取到锁,开始执行");
            }
        });

        thread1.start();
        // 让线程1先执行
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread2.start();
    }
}

运行WaitDemo时,线程1调用wait后会释放lock锁,线程2可以获取到锁执行,之后线程2调用notify唤醒线程1,线程1重新竞争锁后继续执行。而运行SleepDemo时,线程1调用sleep期间不会释放lock锁,线程2需要等待线程1执行完同步块释放锁后才能执行。

Java线程状态变化说明

Java线程的生命周期共有6种状态,定义在Thread.State枚举中,分别是:

  • NEW:线程创建后尚未启动的状态
  • RUNNABLE:线程正在Java虚拟机中执行,或者正在等待操作系统分配CPU时间片
  • BLOCKED:线程等待获取监视器锁(进入同步代码块时锁被其他线程持有)的状态
  • WAITING:线程无限期等待其他线程执行特定操作的状态,比如调用Object.wait()无超时参数、Thread.join()无超时参数
  • TIMED_WAITING:线程在指定时间内等待的状态,比如调用Thread.sleep(long)Object.wait(long)Thread.join(long)
  • TERMINATED:线程执行完毕或者因异常退出的终止状态

状态流转关系

线程状态的流转遵循以下规则:

  1. NEW状态的线程调用start()方法后进入RUNNABLE状态
  2. RUNNABLE状态的线程尝试进入同步代码块,若锁被其他线程持有则进入BLOCKED状态,获取到锁后回到RUNNABLE状态
  3. RUNNABLE状态的线程调用无超时的wait()join()或者LockSupport.park()会进入WAITING状态,被其他线程唤醒(notify、notifyAll、unpark)后重新竞争锁,竞争成功回到RUNNABLE状态
  4. RUNNABLE状态的线程调用带超时的sleep(long)wait(long)join(long)或者LockSupport.parkNanos()会进入TIMED_WAITING状态,等待超时或者被唤醒后回到RUNNABLE状态
  5. 线程执行完run()方法或者抛出未捕获的异常,会进入TERMINATED状态
注意:WAITING和TIMED_WAITING状态的线程被唤醒后,不会立刻回到RUNNABLE状态,而是需要先重新获取对象锁(如果是通过wait进入的等待状态),获取到锁之后才会继续执行。

结合wait和sleep的使用场景,调用sleep时线程从RUNNABLE变为TIMED_WAITING,等待时间结束后自动回到RUNNABLE;调用wait时线程从RUNNABLE变为WAITING或TIMED_WAITING,同时释放锁,被唤醒后需要重新竞争锁才能回到RUNNABLE状态,这就是两者在状态变化上的核心差异。

waitsleepJava线程线程状态修改时间:2026-07-06 10:57:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。