源本科技 | 码上会

Java Thread.sleep()

2026/01/29
38
0

学习目标

  • 理解 Thread.sleep() 方法的基本作用与使用场景

  • 掌握 Thread.sleep() 的两种重载形式及其参数含义

  • 能够正确处理 sleep() 方法可能抛出的异常

  • 了解 sleep() 在主线程和自定义线程中的实际应用

  • 认识系统负载对实际休眠时间的影响


什么是 Thread.sleep()

Thread.sleep() 是 Java 中 Thread 类提供的一个静态方法,用于暂停当前正在执行的线程一段时间。在这段休眠时间内,该线程不会占用 CPU 资源,也不会参与调度。当指定的时间结束后,线程会重新进入就绪状态,等待 CPU 调度继续执行。

注意:sleep() 暂停的是调用该方法的当前线程,而不是其他线程。


方法签名与参数说明

Java 提供了两个重载版本的 sleep() 方法:

public static void sleep(long millis)
public static void sleep(long millis, int nanos)

参数解释

  • millis:线程需要休眠的毫秒数(必须 ≥ 0)

  • nanos:额外的纳秒数(范围:0 到 999,999),用于更精确地控制休眠时间

例如:Thread.sleep(1000, 500000) 表示休眠 1 秒 + 50 万纳秒(即 1.5 秒)

可能抛出的异常

  • InterruptedException:当其他线程在当前线程休眠期间调用其 interrupt() 方法时抛出

  • IllegalArgumentException:当传入的 millis 为负数,或 nanos 不在 [0, 999999] 范围内时抛出

这两个都是检查型异常,必须显式处理(try-catch 或 throws)


关键特性

  • 静态方法:通过 Thread.sleep() 直接调用,无需线程实例

  • 适用于任何线程:包括主线程(main thread)和用户自定义线程

  • 实际休眠时间可能不精确:受操作系统调度器和系统负载影响,高负载下实际休眠时间可能略长于指定值

  • 单参数版本是 native 方法:底层由 C/C++ 实现;双参数版本由 Java 实现,内部会转换为合适的毫秒 + 纳秒组合


示例代码

在主线程中使用

// 主线程休眠示例
import java.lang.Thread;

class MainDemo {
    public static void main(String[] args) {
        try {
            for (int i = 0; i < 5; i++) {
                Thread.sleep(1000); // 主线程休眠 1 秒
                System.out.print(i + " ");
            }
        } catch (InterruptedException e) {
            System.err.println("线程被中断: " + e.getMessage());
        }
    }
}

输出:

0 1 2 3 4

每隔 1 秒打印一个数字,共 5 次。


在自定义线程中使用

// 自定义线程休眠示例
import java.lang.Thread;

class WorkerThread extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 5; i++) {
                Thread.sleep(1000); // 当前线程休眠 1 秒
                System.out.print(i + " ");
            }
        } catch (InterruptedException e) {
            System.err.println("工作线程被中断: " + e.getMessage());
        }
    }

    public static void main(String[] args) {
        WorkerThread worker = new WorkerThread();
        worker.start(); // 启动新线程
    }
}

输出:

0 1 2 3 4

新创建的线程每隔 1 秒输出一个数字。


传递负数导致异常

// 错误用法:传递负的休眠时间
import java.lang.Thread;

class ErrorDemo {
    public static void main(String[] args) {
        try {
            Thread.sleep(-100); // 非法参数!
        } catch (IllegalArgumentException e) {
            System.err.println(e.getMessage());
        } catch (InterruptedException e) {
            System.err.println("中断异常: " + e.getMessage());
        }
    }
}

输出:

timeout value is negative

传入负数会立即抛出 IllegalArgumentException


异常处理

由于 sleep() 抛出的是检查型异常,推荐使用 try-catch 块进行处理,并根据业务逻辑决定是否记录日志或恢复执行:

try {
    Thread.sleep(2000);
} catch (InterruptedException e) {
    // 恢复中断状态(良好实践)
    Thread.currentThread().interrupt();
    // 可选:记录日志或清理资源
    System.err.println("线程休眠被中断");
}

最佳实践:捕获 InterruptedException 后,通常应调用 Thread.currentThread().interrupt() 以恢复中断状态,便于上层代码感知中断。


系统负载对精度影响

虽然你指定了休眠 1000 毫秒,但实际唤醒时间可能因以下原因延迟:

  • 操作系统调度策略(如 Windows 的默认精度约为 15ms)

  • CPU 负载过高,调度器无法及时唤醒线程

  • 实时性要求高的场景应考虑使用 ScheduledExecutorService 或其他高精度定时机制


重点总结

  • Thread.sleep() 用于暂停当前线程指定时间

  • 有两个重载版本:仅毫秒、毫秒 + 纳秒

  • 必须处理 InterruptedExceptionIllegalArgumentException

  • 是静态方法,直接通过 Thread 类调用

  • 实际休眠时间受系统环境影响,不保证绝对精确

  • 适用于简单延时、模拟耗时操作、控制输出节奏等场景


思考题

  1. 为什么 Thread.sleep() 是静态方法?如果它是实例方法会有什么问题?

  2. 在多线程程序中,如果一个线程在 sleep() 期间被中断,它的后续行为会如何?应该如何正确处理?

  3. 能否用 Thread.sleep() 实现精确的定时任务?如果不可以,Java 中有哪些更合适的替代方案?