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最佳实践,确保线程安全与资源可控。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/7305.html