目录
一.Wait()
二.Sleep()
三.总结Wait()与Sleep()的区别
一.Wait()
在Java中,wait() 方法是 Object类中的一个方法,用于线程间的协作。当一个线程调用wait() 方法时,它会释放对象的锁并进入等待状态,直到其他线程调用相同对象的 notify()或 notifyAll() 方法唤醒它。当其他线程调用相同对象的 notify() 后会唤醒一个处于等待状态线程,而如果是调用 notifyAll() 的话则会唤醒全部的等待状态的线程。
wait() 方法有几种不同的重载形式:
- wait():导致当前线程等待,直到另一个线程调用相同对象的notify()或notifyAll()方法。
- wait(long timeout):导致当前线程等待,直到另一个线程调用相同对象的notify()或notifyAll()方法,或者指定的时间(以毫秒为单位)已过。
- wait(long timeout, int nanos):导致当前线程等待,直到另一个线程调用相同对象的notify()或notifyAll()方法,或者指定的时间已过(以毫秒和纳秒为单位)。
在使用 wait()方法时,需要注意以下几点:
- 必须在同步块或同步方法中调用wait()方法,否则会抛出IllegalMonitorStateException异常。
- 调用wait()方法后,当前线程会释放对象的锁,但不会释放对象的所有权。
- 当一个线程在等待时被中断,会抛出InterruptedException异常。
在之前的文章中,我们有讲到Synchronized的实现会通过Monitor来监视当前线程,对于Monitor中的WaitSet区域就是用来存放被 wait() 置于等待状态的线程,从而就会释放当前锁。
而处于等待状态的线程收到其他线程调用相同对象的 notify()或 notifyAll() 方法唤醒后,就可以重新回到线程队列中去竞争这个锁。
二.Sleep()
在Java中,sleep() 方法是Thread类的一个静态方法,用于使当前线程暂停执行一段时间。它接受一个以毫秒为单位的参数,表示线程要睡眠的时间长度。调用sleep() 方法会导致当前线程暂时放弃CPU的执行权,但不会释放锁。当睡眠时间结束或线程被中断时,线程会重新进入可运行状态。另外 sleep() 方法不会释放对象的锁,因此如果一个线程在同步块或同步方法中调用sleep() 方法,其他线程仍然无法访问该对象的同步块或同步方法。
三.总结Wait()与Sleep()的区别
总的来说,wait() 和sleep() 是Java中用于线程控制的两个不同方法,它们的主要区别在于用途和影响。
-
所属类和调用方式:
wait()
方法属于Object
类,因此只能在同步代码块或同步方法中调用,并且必须通过持有对象的锁来调用。sleep()
方法是Thread
类的静态方法,可以在任何地方直接调用。
-
锁的释放:
- 在调用
wait()
方法时,线程会释放对象的锁,并进入等待状态,直到被其他线程调用notify()
或notifyAll()
唤醒。 - 调用
sleep()
方法时,线程不会释放锁,它只是暂时放弃CPU的执行权,但其他线程依然无法访问该线程持有的锁。
- 在调用
-
用途:
wait()
通常用于线程间的协作,例如一个线程等待另一个线程完成某个操作后再继续执行。sleep()
通常用于线程的时间控制,例如实现简单的定时功能或控制线程执行顺序。
-
异常处理:
wait()
方法会抛出InterruptedException
异常,因此在调用wait()
方法时需要进行异常处理。sleep()
方法也会抛出InterruptedException
异常,需要进行异常处理。
-
调用方式:
wait()
方法需要在try-catch
块中调用,或者将异常抛出给上层调用者处理。sleep()
方法也需要在try-catch
块中调用,或者将异常抛出给上层调用者处理。
对于二者关于锁的释放的不同可以用下面这个图示来说明,wait方法就相对于让当前线程从工作房间里面出来, 去一个休息室休息,从而把当前房间让给其他线程工作;而sleep方法则相对于是让线程在房间里面原地休息一下,等休息够了后继续干活
本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见