关于 sleep 和 wait 深度对比!

开发
本文我们分析了sleep​ 和 wait,sleep​用于暂停当前线程一段指定时间,但仍保持锁,这常用来控制执行节奏或定时操作。

在计算机编程中,特别是在多线程或并发编程中,sleep 和 wait 是两个非常常见的函数,但它们有不同的用途和工作机制,这篇文章我们将详细地讨论 sleep 和 wait 的区别,包括它们的内部工作原理、应用场景以及详细的示例代码,以帮助更全面地理解它们。

sleep

工作机制:

  • 暂停当前线程: sleep 方法暂停当前执行的线程一段指定的时间,时间结束后线程再恢复执行。
  • 不会释放锁: 即使线程在 sleep 状态下持有锁,它也不会释放。它依然占用着该锁,其他线程无法获得该锁。
  • 线程状态转换: sleep 方法会使线程从运行(RUNNING)状态转换为计时等待(TIMED_WAITING)状态。
  • 静态方法: 它是 Thread 类的静态方法,调用时通过 Thread.sleep 访问。

应用场景:

  • 限流: 控制任务执行的频率,防止线程过度占用CPU资源。
  • 定时任务: 在某个循环中,定时执行某些任务。

示例代码:

public class SleepExample extends Thread {
    public void run() {
        try {
            System.out.println("Thread going to sleep for 2 seconds.");
            Thread.sleep(2000); // 睡眠 2 秒
            System.out.println("Thread woke up after sleeping.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SleepExample thread = new SleepExample();
        thread.start();
    }
}

wait

工作机制:

  • 释放锁并等待通知: wait 方法使当前线程等待,直到其他线程调用当前对象的 notify 或 notifyAll 方法。调用 wait 时,线程会释放它持有的锁。
  • 必须在同步块或同步方法中使用: wait 方法必须在同步块或同步方法中调用,否则会抛出 IllegalMonitorStateException。
  • 线程状态转换: wait 方法会使线程从运行(RUNNING)状态转换为等待(WAITING)状态。
  • 对象方法: 它是 Object 类的方法,所以任何对象都可以调用。

应用场景:

  • 线程间通信: 多个线程协同工作时,一个线程等待某个条件满足后,再被其他线程通知继续执行。
  • 生产者-消费者模型: 经常用于实现生产者-消费者模式中的同步。

示例代码:

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

    public static void main(String[] args) throws InterruptedException {
        // 等待线程
        Thread waitingThread = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Thread waiting for the lock to be released.");
                    lock.wait(); // 进入等待状态并释放锁
                    System.out.println("Thread resumed after lock released.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // 通知线程
        Thread notifyingThread = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Notifying other threads.");
                lock.notify(); // 通知其他等待该锁的线程
                System.out.println("Notified waiting thread.");
            }
        });

        waitingThread.start();
        Thread.sleep(1000); // 确保 waitingThread 先持有锁并进入等待状态
        notifyingThread.start();
    }
}

sleep 和 wait的对比

特性

sleep

wait

释放锁

需要在同步块或方法中

属于

Thread 类

Object 类

引发异常

InterruptedException

InterruptedException 引发机制相同

作用范围

当前调用的线程

当前拥有锁的线程

线程状态改变

变为计时等待(TIMED_WAITING)

变为等待(WAITING)

典型应用场景

暂停线程的一段时间,用于控制节奏或定时操作

线程间通信,生产者-消费者模型等

总结

本文,我们分析了sleep 和 wait,sleep用于暂停当前线程一段指定时间,但仍保持锁,这常用来控制执行节奏或定时操作。wait使线程释放锁并进入等待状态,直到通过 notify/notifyAll 被唤醒,需在同步块中使用,适用于线程间通信如生产者-消费者模型。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2011-05-26 15:52:31

sleep()wait()

2022-01-06 07:03:30

Linux SleepWait

2023-04-28 07:49:13

Javawaitsleep

2023-09-22 08:39:00

sleep函数语言

2024-12-20 16:49:15

MyBatis开发代码

2022-08-02 08:00:49

sleepwait释放锁

2020-07-22 08:06:46

释放锁synchronize线程

2011-07-29 09:24:14

2019-08-30 08:54:05

TypeScriptJavaScript语言

2019-03-06 09:55:54

Python 开发编程语言

2018-01-10 15:03:27

前端TypeScriptJavaScript

2015-01-19 09:33:41

Rails\Djang

2024-12-16 13:00:00

SpringJava

2021-06-07 11:33:24

服务器优化TIME-WAIT

2009-11-16 16:23:10

PHP数组遍历

2023-06-12 08:00:00

聊天机器人ChatGPT人工智能

2020-08-28 17:54:31

深度学习框架

2023-05-14 22:00:01

2024-10-14 17:24:32

2011-04-13 14:04:14

Java数组
点赞
收藏

51CTO技术栈公众号