Java并发编程里,Thread.sleep是让当前正在执行的线程暂停指定时长的常用方法,属于线程调度相关的核心API,在很多需要控制线程执行节奏的场景中都会用到。

Thread.sleep的基本用法
Thread.sleep是Thread类的静态方法,调用时会让当前执行的线程进入休眠状态,暂停执行指定的时间,时间单位支持毫秒、纳秒等。最基础的用法是传入毫秒数作为参数,示例代码如下:
public class SleepDemo {
public static void main(String[] args) {
System.out.println("线程开始执行,时间:" + System.currentTimeMillis());
try {
// 让当前线程休眠1000毫秒,也就是1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
// 处理中断异常
e.printStackTrace();
}
System.out.println("线程休眠结束,时间:" + System.currentTimeMillis());
}
}
除了毫秒参数,Thread类还提供了支持时间单位的重载方法,需要配合TimeUnit枚举使用,可读性更强,示例代码如下:
import java.util.concurrent.TimeUnit;
public class SleepWithUnitDemo {
public static void main(String[] args) {
System.out.println("开始休眠");
try {
// 使用TimeUnit指定休眠1秒,比直接写1000可读性更好
TimeUnit.SECONDS.sleep(1);
// 也可以指定其他单位,比如休眠500毫秒
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("休眠结束");
}
}
Thread.sleep的休眠机制核心特性
线程状态变化
线程调用Thread.sleep之后,会从运行状态(RUNNABLE)进入限时等待状态(TIMED_WAITING),在休眠时间结束之前,线程不会参与CPU调度,也不会执行任何业务逻辑。当休眠时间到了之后,线程会重新进入就绪状态,等待CPU分配时间片后继续执行。
不会释放锁资源
这是Thread.sleep和wait()方法最核心的区别之一。如果线程在持有对象锁的情况下调用了Thread.sleep,休眠过程中不会释放已经持有的锁,其他等待该锁的线程仍然无法获取锁执行。示例代码如下:
public class SleepLockDemo {
private static final Object lock = new Object();
public static void main(String[] args) {
// 线程1获取锁后休眠
new Thread(() -> {
synchronized (lock) {
System.out.println("线程1获取锁,开始休眠2秒");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1休眠结束,释放锁");
}
}).start();
// 线程2等待获取锁
new Thread(() -> {
synchronized (lock) {
System.out.println("线程2获取锁,执行逻辑");
}
}).start();
}
}
运行上述代码会发现,线程1休眠的2秒内,线程2不会执行,只有线程1休眠结束释放锁之后,线程2才能获取锁执行。
休眠时间的精度问题
Thread.sleep指定的休眠时间只是线程暂停的最少时间,实际休眠时间可能会更长。因为操作系统的线程调度本身存在精度限制,部分系统的调度时间片可能是10毫秒或者更长,所以如果指定休眠1毫秒,实际可能会休眠10毫秒甚至更久。如果需要高精度的定时,不建议使用Thread.sleep。
使用Thread.sleep的注意事项
必须处理中断异常
Thread.sleep方法声明了抛出InterruptedException,这是一个受检异常,调用时必须捕获处理,不能抛出到run方法之外。当线程在休眠过程中被其他线程调用interrupt()方法中断时,就会抛出这个异常,同时线程的中断状态会被清除。示例代码如下:
public class SleepInterruptDemo {
public static void main(String[] args) throws InterruptedException {
Thread sleepThread = new Thread(() -> {
System.out.println("线程开始休眠3秒");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println("线程被中断,中断状态:" + Thread.currentThread().isInterrupted());
// 可以在这里做中断后的处理逻辑,比如退出循环
return;
}
System.out.println("线程正常休眠结束");
});
sleepThread.start();
// 主线程休眠1秒后中断休眠线程
Thread.sleep(1000);
sleepThread.interrupt();
}
}
避免在不必要场景使用
Thread.sleep会阻塞当前线程,如果在核心业务线程或者IO线程中滥用,会导致线程无法及时处理其他任务,降低程序的整体性能。如果是需要等待某个条件满足的场景,优先考虑使用wait/notify或者Condition机制,而不是用Thread.sleep轮询。
时间单位的选择
如果休眠时间比较长,或者需要明确的时间单位,优先使用TimeUnit的sleep方法,而不是直接传入毫秒数,这样可以提升代码的可读性,也避免计算毫秒数时出现错误。比如需要休眠1分钟,用TimeUnit.MINUTES.sleep(1)比Thread.sleep(60000)更清晰。
常见误区说明
很多开发者会误以为Thread.sleep可以让其他线程先执行,实际上它只是暂停当前线程,不会主动让出CPU给其他特定线程,其他线程能否执行取决于操作系统的线程调度策略。如果需要控制线程的执行顺序,应该使用线程通信相关的机制,而不是依赖Thread.sleep。
另外,Thread.sleep不会让线程进入阻塞状态(BLOCKED),阻塞状态通常是线程等待获取锁时才会进入的,而sleep进入的是TIMED_WAITING状态,属于等待状态的一种,二者不能混淆。
Thread.sleepJava并发编程线程休眠时间单位中断异常修改时间:2026-07-06 11:03:28