Java中sleep()方法和wait()方法用法和区别

一、概述  
  一个 线程修改了一个象的,而另一个线程感知到了化,然后行相的操作,整个程开始于一个线程,而最终执行又是另一个线程。前者是生者,后者就是消者,种模式隔离了做什么what)和怎么做How),在功能面上实现了解耦,体系构上具了良好的伸 ,Java就是通过等待和通知机制来实现这种功能的。
当一个线程完成了特定的环节时候,就去等待另外的线程执行,第二个线程准备好第一个线程需要的条件后,就去唤醒第一个线程,这样实现了两个线程的通信协作。

让线程停下来等待,可以通过Thread类的静态方法,Thread.sleep(millis); 也可以使用Object及其子类都具备的wait()/wait(millis)方法;两者的异同在下面展开

二、Thread.sleep() 和 Object.wait()的区别
1. 调用Thread.sleep(),当前线程不释放锁,睡眠过程中一直持有锁对象,睡眠时间过后继续执行;
2.调用wait()方法,线程释放锁对象,直到这个锁对象的notify或者notifyAll()被调用,才会被唤醒,重新争夺锁。
3. sleep()是Thread类的静态方法,wait/notify是Object类的通用方法,这也符合Java中锁的理念,对象都可以作为锁。

注意:
1. wait()方法只能用于同步代码块范围内,且只能对同步方法或者同步代码块持有的锁对象进行wait和notify操作,否则会报错IllegalMonitorStateException
2. 两者都可能抛出InterruptedException

三、show me the code
 
  
  1. import java.text.SimpleDateFormat;
  2. import java.util.Date;
  3. public class TestSleepAndWait {
  4. public static void main(String[] args) {
  5. new Thread1().start();
  6. try {
  7. Thread.sleep(100);
  8. } catch (InterruptedException e) {
  9. e.printStackTrace();
  10. }
  11. new Thread2().start();
  12. }
  13. }
  14. class Thread1 extends Thread{
  15. private void sout(String s){
  16. System.out.println(s+" "+new SimpleDateFormat("HH:mm:ss:SS").format(new Date()));
  17. }
  18. @Override
  19. public void run() {
  20. sout("enter Thread1.run");
  21. synchronized (TestSleepAndWait.class){//wait只能在同步代码块或者同步方法中使用
  22. sout("Thread1 is going to wait");
  23. try {
  24. TestSleepAndWait.class.wait(); // 这里只能使用持有锁TestSleepAndWait.class.wait(),使用其他对象则报错java.lang.IllegalMonitorStateException
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. }
  28. sout("after waiting, thread1 is going on");
  29. sout("thread1 is over");
  30. }
  31. }
  32. }
  33. class Thread2 extends Thread{
  34. private void sout(String s){
  35. System.out.println(s+" "+new SimpleDateFormat("HH:mm:ss:SS").format(new Date()));
  36. }
  37. @Override
  38. public void run() {
  39. sout("enter Thread2.run");
  40. synchronized (TestSleepAndWait.class){//wait只能在同步代码块或者同步方法中使用
  41. sout("Thread2 is going to notify");
  42. TestSleepAndWait.class.notify(); 这里只能使用持有锁TestSleepAndWait.class
  43. sout("thread2 is going to sleep 10ms");
  44. try {
  45. Thread.sleep(10);
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. }
  49. sout("after sleeping, thread2 is going on");
  50. sout("thread2 is over");
  51. }
  52. }
  53. }
运行结果
 
   
  1. enter Thread1.run 22:49:28:588
  2. Thread1 is going to wait 22:49:28:588
  3. enter Thread2.run 22:49:28:668
  4. Thread2 is going to notify 22:49:28:668
  5. thread2 is going to sleep 10ms 22:49:28:668
  6. after sleeping, thread2 is going on 22:49:28:680
  7. thread2 is over 22:49:28:680
  8. after waiting, thread1 is going on 22:49:28:680
  9. thread1 is over 22:49:28:680
分析:
    可以看到,两个线程都使用TestSleepAndWait.class作为锁对象,
    线程1首先获得执行权后,调用了锁对象的wait(),进而释放了锁和共享资源;
    这时候线程2才获得执行权,而后进入了10ms的休眠期;    在10ms的休眠期间尽管线程2调用了锁对象的notify方法,线程1也没能获得执行权,这是因为线程2没有释放锁,线程1无法继续执行同步代码,直到线程2休眠结束,并执行完后续逻辑后,线程一才获得执行权。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值