java基础---sleep和wait的区别

本文详细解析了Java中线程控制方法wait与sleep的区别,包括锁行为的影响及线程状态转换等内容。

/*

wait和sleep区别
	1.wait可以指定也可以不用指定时间,
	sleep必须指定时间
	
	2.在同步中,对cpu的执行权释放不同
	wait:释放执行权,释放锁;
	sleep:释放执行权,不释放锁;


	1.首先,要记住这个差别,“sleep是Thread类的方法,wait是Object类中定义的方法”。
尽管这两个方法都会影响线程的执行行为,但是本质上是有区别的。

	2.Thread.sleep不会导致锁行为的改变,如果当前线程是拥有锁的,那么Thread.sleep
不会让线程释放锁。如果能够帮助你记忆的话,可以简单认为和锁相关的方法都定义在
Object类中,因此调用Thread.sleep是不会影响锁的相关行为。

	3.Thread.sleep和Object.wait都会暂停当前的线程,对于CPU资源来说,不管是哪种方
式暂停的线程,都表示它暂时不再需要CPU的执行时间。OS会将执行时间分配给其它线程。
区别是,调用wait后,需要别的线程执行notify/notifyAll才能够重新获得CPU执行时间。
线程的状态参考 Thread.State的定义。新创建的但是没有执行(还没有调用start())的
线程处于“就绪”,或者说Thread.State.NEW状态。

	4.Thread.State.BLOCKED(阻塞)表示线程正在获取锁时,因为锁不能获取到而被迫暂停
执行下面的指令,一直等到这个锁被别的线程释放。BLOCKED状态下线程,OS调度机制需要
决定下一个能够获取锁的线程是哪个,这种情况下,就是产生锁的争用,无论如何这都是很
耗时的操作。
*/


class  
{
	public static void main(String[] args) 
	{
		System.out.println("Hello World!");
	}
}



线程间的状态转换: 

1. 新建(new):新创建了一个线程对象。

2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

3. 运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。

4. 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。

(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

5. 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

Java中的`wait()``sleep()`方法都是用于线程控制的方法,它们都使线程暂停执行,但它们之间存在一些显著的区别。以下是对这两个方法的详细对比: 1. **所属类** - **`wait()`**:属于`Object`类的方法。 - **`sleep()`**:属于`Thread`类的方法。 2. **调用方式** - **`wait()`**:必须在同步块(synchronized块)或同步方法中调用,否则会抛出`IllegalMonitorStateException`异常。 - **`sleep()`**:可以在任何地方调用,需要在同步块或同步方法中。 3. **锁的处理机制** - **`wait()`**:会释放当前持有的锁,让出CPU资源,并且线程进入等待状态,直到被其他线程唤醒。 - **`sleep()`**:会释放锁,线程会一直占用CPU资源,只是暂停执行一段时间。 4. **唤醒机制** - **`wait()`**:需要被其他线程调用`notify()`或`notifyAll()`方法唤醒。 - **`sleep()`**:时间到达后自动苏醒,需要其他线程唤醒。 5. **用途** - **`wait()`**:通常用于线程间通信协作,例如生产者-消费者模型。 - **`sleep()`**:通常用于让线程暂停执行一段时间,例如模拟延迟操作。 6. **异常处理** - **`wait()`**:可能会抛出`InterruptedException`异常,需要捕获处理。 - **`sleep()`**:同样可能抛出`InterruptedException`异常,也需要捕获处理。 7. **线程进入的状态** - **`wait()`**:调用无参数的`wait()`方法,线程会进入`WAITING`无时限等待状态;如果指定了超时时间,则进入`TIMED_WAITING`有时限等待状态。 - **`sleep()`**:线程会进入`TIMED_WAITING`有时限等待状态。 8. **示例代码** - **`wait()`**: ```java public class WaitExample { public static void main(String[] args) { final Object lock = new Object(); Thread thread1 = new Thread(() -> { synchronized (lock) { try { System.out.println("Thread 1 is waiting..."); lock.wait(); System.out.println("Thread 1 is resumed."); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread thread2 = new Thread(() -> { synchronized (lock) { System.out.println("Thread 2 is notifying..."); lock.notify(); } }); thread1.start(); thread2.start(); } } ``` - **`sleep()`**: ```java public class SleepExample { public static void main(String[] args) { Thread thread = new Thread(() -> { try { System.out.println("Thread is sleeping..."); Thread.sleep(2000); // 暂停2秒 System.out.println("Thread is resumed."); } catch (InterruptedException e) { e.printStackTrace(); } }); thread.start(); } }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值