今天完成了实验室纳新网站的工作,大体功能都已经完善,也和前端测试过了,费了点时间,而且今天大部分时间在看langchain4j的东西,就简单复习一下八股,等会再复习一下算法题吧

在Java并发编程中,sleep()wait()都用于暂停线程执行,但它们在设计目的、行为和使用场景上有本质区别。以下是详细对比及示例说明:

核心区别总结

特性 sleep() wait()
所属类 Thread类的静态方法 Object类的实例方法
锁释放 ❌ 不释放任何锁 ✅ 释放对象锁(只释放调用它的对象的锁)
唤醒条件 超时结束或被中断(InterruptedException 需其他线程调用notify()/notifyAll()或超时
同步要求 无需在同步块中调用 必须在synchronized块或方法中使用
用途 单纯暂停当前线程 线程间通信(协调多个线程的执行顺序)

示例代码解析

示例1:sleep()不释放锁(独占锁场景)
public class SleepDemo {
    public static void main(String[] args) {
        Object lock = new Object();
        
        new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread-1: 获得锁,开始sleep(2000)");
                try {
                    Thread.sleep(2000); // 暂停2秒,但不会释放lock锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread-1: sleep结束,释放锁");
            }
        }).start();

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread-2: 获得锁"); // 需等待Thread-1释放锁
            }
        }).start();
    }
}

输出结果:

Thread-1: 获得锁,开始sleep(2000)
(等待2秒...)
Thread-1: sleep结束,释放锁
Thread-2: 获得锁

结论sleep()期间不释放锁,其他线程无法进入同步块。

示例2:wait()释放锁(线程协作场景)
public class WaitDemo {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        
        // 等待线程
        new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread-1: 获得锁,调用wait()释放锁");
                try {
                    lock.wait(); // 释放lock锁,进入等待状态
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread-1: 被唤醒,重新获得锁");
            }
        }).start();

        Thread.sleep(500); // 确保Thread-1先执行
        
        // 唤醒线程
        new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread-2: 获得锁,执行notify()");
                lock.notify(); // 唤醒Thread-1(但需退出同步块才释放锁)
                System.out.println("Thread-2: notify()后,仍持有锁2秒");
                try {
                    Thread.sleep(2000); // sleep()不释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

输出结果:

Thread-1: 获得锁,调用wait()释放锁
Thread-2: 获得锁,执行notify()
Thread-2: notify()后,仍持有锁2秒
(等待2秒...)
Thread-1: 被唤醒,重新获得锁

结论

  1. wait()立即释放锁Thread-2得以进入同步块。
  2. Thread-2调用notify()后,Thread-1需等待Thread-2退出同步块(释放锁)才能重新获得锁并继续执行。

关键点详解

  1. 锁释放机制

    • sleep():线程暂停但保留所有锁,可能导致其他线程阻塞。
    • wait():释放调用对象的锁,允许其他线程获得锁并执行。
  2. 唤醒方式

    • sleep():超时结束或调用线程的interrupt()方法。
    • wait():需其他线程显式调用notify()/notifyAll(),或超时(若设置了超时时间)。
  3. 使用约束

    • wait()/notify()必须synchronized代码块中调用,否则抛出IllegalMonitorStateException
    • sleep()可在任何上下文调用(但需处理InterruptedException)。
  4. 设计目的

    • sleep():用于定时任务(如轮询间隔)、模拟耗时操作。
    • wait():用于线程协作(如生产者-消费者模型),避免忙等待(busy-waiting)。

经典应用场景

  • sleep():定时任务调度(如每5秒检查一次状态)、模拟网络延迟。
  • wait()/notify():线程间协调(如生产者生产后通知消费者)、条件等待(等待资源就绪)。

重要提示:Java 5+推荐使用java.util.concurrent包的ConditionCountDownLatch等高级工具替代wait()/notify(),以简化并发控制。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐