上一篇
Java如何实现延迟执行?
- 后端开发
- 2025-05-30
- 3715
在Java中实现延时操作,常用
Thread.sleep()方法暂停当前线程执行,如
Thread.sleep(1000)暂停1秒;或使用
TimeUnit类提供更可读的时间单位,TimeUnit.SECONDS.sleep(1)
,注意该方法会抛出InterruptedException`需捕获处理。
Thread.sleep():基础延时
原理
通过阻塞当前线程指定时间实现延时,精度受系统计时器和调度器影响(毫秒级)。
代码示例:
try {
// 延时3秒(3000毫秒)
Thread.sleep(3000);
System.out.println("延时结束");
} catch (InterruptedException e) {
// 必须处理中断异常
Thread.currentThread().interrupt(); // 恢复中断状态
System.out.println("线程被中断");
}
适用场景:
简单单线程任务、测试代码。
注意事项:
- 会阻塞当前线程,不适用高并发场景。
- 必须捕获
InterruptedException,否则可能导致线程状态异常。
TimeUnit:可读性更高的延时
原理
基于Thread.sleep()的封装类,提供时间单位转换(纳秒/微秒/毫秒/秒等),提升代码可读性。
代码示例:
import java.util.concurrent.TimeUnit;
try {
TimeUnit.SECONDS.sleep(5); // 延时5秒
System.out.println("5秒延时完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
适用场景:
需明确时间单位的场景(如秒级/分钟级延时)。
优势:
避免手动单位换算(如MINUTES.toMillis(2))。

ScheduledExecutorService:异步精准调度
原理
使用线程池调度任务,支持单次或周期性延时,避免直接阻塞线程。
代码示例:
import java.util.concurrent.*;
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// 延时2秒后执行任务
scheduler.schedule(() -> {
System.out.println("延时任务执行");
}, 2, TimeUnit.SECONDS);
// 关闭线程池(实际应用中需合理管理)
scheduler.shutdown();
适用场景:
高并发定时任务、需要异步执行的延时操作。
优势:
- 线程复用,资源消耗低。
- 支持异常处理(通过
Future对象)。
Timer 与 TimerTask:传统定时器
原理
通过Timer调度TimerTask任务实现延时。
代码示例:

import java.util.Timer;
import java.util.TimerTask;
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("延时1.5秒执行");
timer.cancel(); // 终止定时器
}
}, 1500); // 1500毫秒
适用场景:
简单单次延时任务(如倒计时)。
缺点:
- 单个
Timer线程阻塞会导致所有任务延迟。 - Java 1.5+推荐改用
ScheduledExecutorService。
Object.wait():结合同步机制的延时
原理
在同步代码块中暂停线程,需通过notify()/notifyAll()唤醒。
代码示例:
synchronized (lockObject) {
try {
lockObject.wait(4000); // 延时4秒
System.out.println("唤醒或超时后继续");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
适用场景:
多线程协作(如生产者-消费者模型)。
注意事项:

- 必须在
synchronized代码块中使用。 - 可被其他线程提前唤醒(需循环检查条件)。
选择建议与注意事项
- 精度要求
- 高精度需求(如毫秒内):考虑
System.nanoTime()循环检查(谨慎使用,占用CPU)。 - 普通精度:
Thread.sleep()或TimeUnit足够。
- 高精度需求(如毫秒内):考虑
- 并发性能
- 避免在主线程或UI线程中使用阻塞方法(如
sleep())。 - 多任务调度优先选
ScheduledExecutorService。
- 避免在主线程或UI线程中使用阻塞方法(如
- 资源管理
- 使用线程池后必须调用
shutdown(),避免内存泄漏。
- 使用线程池后必须调用
- 替代方案
- Spring框架:
@Scheduled注解实现声明式定时任务。 - Quartz:复杂任务调度(分布式支持)。
- Spring框架:
引用说明: 参考Oracle官方文档
- Thread.sleep()
- ScheduledExecutorService
实践代码遵循Java Concurrency最佳实践,确保线程安全与资源可控。
