3.线程睡眠的Thread.sleep和让出cpu的Thread.yield静态方法

本文详细解析Thread.sleep方法如何影响线程睡眠和锁资源,以及Thread.yield如何让出CPU而不释放锁。通过实例演示和异常处理,揭示两者在并发控制中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Thread.sleep方法

总结:代码块内调用Thread.sleep方法不会释放监视器等锁资源,被其他线程中断后会抛出中断异常。

验证sleep不会释放锁资源代码示例

如果线程A获取了锁资源,睡眠过程中,线程B也想获取锁资源,但是获取失败。这间接验证了Thread.sleep静态方法睡眠过程中不会释放锁资源。

private static final Lock LOCK =  new ReentrantLock();
	public  static void main(String[] args) {
		Thread threadA = new Thread(new Runnable() {
			@Override
			public void run() {
				LOCK.lock();
				try {
					System.out.println("线程A开始睡眠");
						Thread.sleep(2000);
						System.out.println("线程A睡眠结束");
				}catch (Exception e) {
					e.printStackTrace();
				} finally {
					LOCK.unlock();
				}
			}
		});
		Thread threadB = new Thread(new Runnable() {
			@Override
			public void run() {
				LOCK.lock();
				try {
					System.out.println("线程B开始执行");
				} finally {
					LOCK.unlock();
				}
			}
		});
		threadA.start();
		threadB.start();
	}

输出:

线程A开始睡眠
线程A睡眠结束
线程B开始执行

验证sleep睡眠过程被中断后抛出中断异常代码示例

线程在sleep过程中,如果被其他线程中断,会抛出中断异常。threadA睡眠过程中,被main线程中断后,抛出InterruptedException异常。

	private static final Lock LOCK =  new ReentrantLock();
	public  static void main(String[] args) {
		Thread threadA = new Thread(new Runnable() {
			@Override
			public void run() {
				LOCK.lock();
				try {
					System.out.println("线程A开始睡眠");
						Thread.sleep(5000);
						System.out.println("线程A睡眠结束");
				}catch (InterruptedException e) {
					e.printStackTrace();
				} finally {
					LOCK.unlock();
				}
			}
		});
		threadA.start();//开启threadA线程
		try {
			System.out.println("main线程睡眠开始");
			Thread.sleep(2000);
			System.out.println("main线程睡眠结束");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		threadA.interrupt();//main线程内中断threaA
	}

输出:

main线程睡眠开始
线程A开始睡眠
main线程睡眠结束
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at java.lang.Thread.run(Thread.java:748)

二、Thread.yield方法

总结:yield方法告知cpu调度器,当前线程请求让出自己的cpu使用。线程让出cpu后处于就绪状态。下次cpu调度还可能有限调度到刚刚让出cpu的线程。

和sleep和wait不同的是:sleep方法让出cpu到指定时间,阻塞挂起,但是不释放锁;wait方法让出cpu直到指定时间或被notify,阻塞挂起,同时释放锁资源。而yield方法仅仅是让出cpu,随后进入就绪状态。
 

<think>我们正在讨论Java中的Thread.sleep()方法。根据用户要求,我们需要解释其功能、用法,并提供示例。同时,根据系统指令,我们需要使用正确的LaTeX格式,用中文回答,并生成相关问题。功能:Thread.sleep()是Java中用于使当前正在执行的线程暂停执行一段时间的方法。它属于Thread类的静态方法。调用此方法会让当前线程进入“休眠”状态,即从运行状态转为阻塞状态(TIMED_WAITING),在指定的时间过后,线程会重新进入可运行状态,等待CPU调度。用法:1.方法签名:-`publicstaticvoidsleep(longmillis)throwsInterruptedException`-`publicstaticvoidsleep(longmillis,intnanos)throwsInterruptedException`(可以指定毫秒纳秒)2.参数:-`millis`:休眠的毫秒数(非负)-`nanos`:附加的纳秒数(0-999999)3.异常:-抛出`InterruptedException`:当线程在休眠期间被中断时抛出。这意味着如果其他线程中断了当前休眠的线程,则sleep方法会抛出此异常。4.注意点:-sleep期间,线程不会释放已经持有的锁(与wait()不同)。-sleep时间不是精确的,受系统计时器调度器精度影响。-sleep(0)表示当前线程放弃剩余时间片,进入就绪状态,但可能立即又被调度。示例:我们将提供两个示例,一个是基本用法,另一个是处理中断的示例。示例1:基本用法(休眠2秒)```javapublicclassSleepExample{publicstaticvoidmain(String[]args){System.out.println("Start");try{//当前线程休眠2000毫秒(2秒)Thread.sleep(2000);}catch(InterruptedExceptione){System.out.println("Interrupted!");}System.out.println("End");}}```运行结果:```Start(等待2秒后)End```示例2:处理中断```javapublicclassInterruptSleepExample{publicstaticvoidmain(String[]args){ThreadsleepingThread=newThread(()->{System.out.println("Sleepingthreadstarts");try{Thread.sleep(5000);//计划休眠5秒}catch(InterruptedExceptione){System.out.println("Sleepingthreadwasinterrupted!");}System.out.println("Sleepingthreadends");});sleepingThread.start();//主线程等待1秒后中断sleepingThreadtry{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}sleepingThread.interrupt();//中断休眠的线程}}```运行结果:```Sleepingthreadstarts(1秒后)Sleepingthreadwasinterrupted!Sleepingthreadends```注意事项:-在实际编码中,必须处理`InterruptedException`,因为它是一个受检异常。-线程被中断后,中断状态会被清除(即调用`Thread.interrupted()`会返回false,除非在catch块中重新设置中断状态)。关于精度问题:Thread.sleep()的休眠时间并不精确,它依赖于操作系统的计时器调度机制。我们可以通过以下代码测试实际休眠时间:```javapublicclassSleepPrecisionTest{publicstaticvoidmain(String[]args){longstart=System.nanoTime();try{Thread.sleep(100);//计划休眠100毫秒}catch(InterruptedExceptione){e.printStackTrace();}longend=System.nanoTime();longduration=(end-start)/1_000_000;//转换为毫秒System.out.println("实际休眠时间:"+duration+"毫秒");}}```实际输出可能略大于100毫秒,例如:102毫秒。总结:Thread.sleep()是控制线程执行时间间隔的重要方法,常用于模拟耗时操作、轮询等待等场景。使用时需注意异常处理精度问题。相关问题:根据系统指令,我们需要生成相关问题。§§相关问题§§1.Thread.sleep()与Object.wait()方法有什么区别?2.如何正确响应线程中断(InterruptedException)?3.Java中,除了Thread.sleep(),还有哪些方法可以让线程暂停执行?4.Thread.sleep(0)有什么特殊作用?5.在多线程编程中,使用Thread.sleep()可能会遇到哪些问题?</think>### Thread.sleep() 方法详解 #### 功能 `Thread.sleep()` 是 Java 中用于**暂停当前线程执行**的静态方法: 1. 使当前线程进入 `TIMED_WAITING` 状态 2. 不释放已持有的锁资源(与 `wait()` 不同) 3. 休眠时间受系统计时器精度限制,存在微小误差 4. 休眠期间可被中断(触发 `InterruptedException`) #### 用法 ```java // 基本语法(毫秒为单位) Thread.sleep(long millis); // 高精度语法(毫秒+纳秒) Thread.sleep(long millis, int nanos); ``` **重要特性**: - ⚠️ 必须捕获 `InterruptedException` - ⏱️ 实际休眠时间 ≈ 参数值 ± 系统调度误差 - 🔒 持有锁时调用不会释放锁(见引用[4]示例) - 🚦 调用 `sleep(0)` 会触发线程调度但不休眠(见引用[1]) #### 示例代码 **基础用法**: ```java public class SleepDemo { public static void main(String[] args) { System.out.println("开始执行"); try { Thread.sleep(2000); // 暂停2秒 } catch (InterruptedException e) { System.out.println("线程被中断!"); } System.out.println("执行结束"); } } ``` 输出: ``` 开始执行 (等待2秒) 执行结束 ``` **带锁场景**(引用[4]): ```java synchronized (lock) { System.out.println("持有锁"); Thread.sleep(1000); // 休眠但不释放锁 System.out.println("保持锁继续执行"); } ``` **精度测试**(引用[3]): ```java long start = System.currentTimeMillis(); Thread.sleep(100); // 计划休眠100ms long duration = System.currentTimeMillis() - start; System.out.println("实际休眠: " + duration + "ms"); // 输出可能为 102ms(系统误差) ``` #### 注意事项 1. **中断处理**:必须处理 `InterruptedException`,通常选择: - 恢复中断状态:`Thread.currentThread().interrupt()` - 终止线程执行 2. **时间精度**:不适用于高精度定时任务(考虑 `ScheduledExecutorService`) 3. **锁机制**:在同步代码块中使用时,其他线程会阻塞等待锁释放 4. **替代方案**:短时等待建议用 `Thread.onSpinWait()`(见引用[1]) > 关键区别:`sleep()` 是**主动暂停**,`yield()` 是**让出CPU**(见引用[5])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值