线程的等待唤醒机制

( 1 )等待唤醒机制就是用于解决线程间通信的问题的,使用到的3个方法的含义如下:
wait:告诉当前线程放弃执行权,并放弃监视器(锁)并进入阻塞状态,直到其他线程持有获得执行权,并持有了相同的监视器(锁)并调用notify为止。
notify:唤醒持有同一个监视器(锁)中调用wait的第一个线程,例如,餐馆有空位置后,等候就餐最久的顾客最先入座。注意:被唤醒的线程是进入了可运行状态。等待cpu执行权。
notifyAll:唤醒持有同一监视器中调用wait的所有的线程。


( 2 )调用wait和notify方法需要注意的细节:
wait方法与notify方法必须要由同一个锁对象调用。因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。
wait方法与notify方法是属于Object类的方法的。因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。
wait方法与notify方法必须要在同步代码块或者是同步函数中使用。因为:必须要通过锁对象调用这2个方法。

( 3 ) waite和sleep方法的区别
1.相同之处:
线程调用wait()或者是sleep()方法都会进入临时阻塞状态,会释放cpu的执行权。调用时都需要处理 InterruptedException异常。

2.不同之处:
wait(): 释放资源,释放锁。是Object的方法。
sleep():释放资源,不释放锁。是Thread的静态方法

下面通过例子来说明.
[java]  view plain  copy
  1. /** 
  2.  * 要实现的效果就是,有一个水池,水池的容量为50L,一个放水线程,负责放水,每200毫秒放出1L水,当水放完后,通知注水线程工作,同时放水线程停止工作; 
  3.  * 注水线程每200毫秒注水1L,水注满时,再通知放水线程继续工作,同时注水线程停止工作. 
  4.  *  
  5.  * @author mChenys 
  6.  *  
  7.  */  
  8. public class _Main5 {  
  9.     public static void main(String[] args) {  
  10.         Pool pool = new Pool();  
  11.         WaterIn in = new WaterIn(pool, "注水线程");  
  12.         WaterOut out = new WaterOut(pool, "放水线程");  
  13.         in.start();  
  14.         out.start();  
  15.     }  
  16. }  
  17.   
  18. /** 
  19.  * 水池,容量为50L 
  20.  *  
  21.  * @author mChenys 
  22.  *  
  23.  */  
  24. class Pool {  
  25.     public int MAX_VLAUE = 50;  
  26.     public int curr_value = 0;  
  27. }  
  28.   
  29. /** 
  30.  * 注水线程 
  31.  *  
  32.  * @author mChenys 
  33.  *  
  34.  */  
  35. class WaterIn extends Thread {  
  36.     private Pool pool;  
  37.   
  38.     public WaterIn(Pool pool, String name) {  
  39.         super(name);  
  40.         this.pool = pool;  
  41.     }  
  42.   
  43.     @Override  
  44.     public void run() {  
  45.         while (true) {  
  46.             synchronized (pool) {  
  47.                 try {  
  48.                     if (pool.curr_value < pool.MAX_VLAUE) {  
  49.                         // 加水  
  50.                         Thread.sleep(200);  
  51.                         pool.curr_value += 1;  
  52.                         System.out.println(this.getName() + "正在加水,加入 "  
  53.                                 + pool.curr_value + " L水");  
  54.                     } else if (pool.curr_value == pool.MAX_VLAUE) {  
  55.   
  56.                         System.out.println(this.getName()  
  57.                                 + "水已加满!!,可以放水了......");  
  58.                         pool.notify();// 唤醒放水线程  
  59.                         pool.wait();// 当前线程等待,释放锁对象  
  60.                     }  
  61.                 } catch (InterruptedException e) {  
  62.                     e.printStackTrace();  
  63.                 }  
  64.             }  
  65.         }  
  66.     }  
  67. }  
  68.   
  69. /** 
  70.  * 放水线程 
  71.  *  
  72.  * @author mChenys 
  73.  *  
  74.  */  
  75. class WaterOut extends Thread {  
  76.     private Pool pool;  
  77.   
  78.     public WaterOut(Pool pool, String name) {  
  79.         super(name);  
  80.         this.pool = pool;  
  81.     }  
  82.   
  83.     @Override  
  84.     public void run() {  
  85.         while (true) {  
  86.             synchronized (pool) {  
  87.                 try {  
  88.                     if (pool.curr_value > 0) {  
  89.                         // 放水  
  90.                         Thread.sleep(200);  
  91.                         pool.curr_value -= 1;  
  92.                         System.out.println(this.getName() + "开始放水,放出 "  
  93.                                 + (pool.MAX_VLAUE - pool.curr_value) + " L水");  
  94.   
  95.                     } else if (pool.curr_value == 0) {  
  96.                         System.out.println(this.getName() + "水已放完,可以加水了.....");  
  97.                         pool.notify();// 唤醒注水线程  
  98.                         pool.wait();// 当前线程等待,释放锁对象  
  99.                     }  
  100.                 } catch (InterruptedException e) {  
  101.                     e.printStackTrace();  
  102.                 }  
  103.             }  
  104.         }  
  105.     }  
  106. }  

运行效果:
[html]  view plain  copy
  1. 注水线程正在加水,加入 20 L水  
  2. 注水线程正在加水,加入 40 L水  
  3. 注水线程正在加水,加入 60 L水  
  4. 注水线程正在加水,加入 80 L水  
  5. 注水线程正在加水,加入 100 L水  
  6. 注水线程正在加水,加入 120 L水  
  7. 注水线程正在加水,加入 140 L水  
  8. 注水线程正在加水,加入 160 L水  
  9. 注水线程正在加水,加入 180 L水  
  10. 注水线程正在加水,加入 200 L水  
  11. 注水线程正在加水,加入 220 L水  
  12. 注水线程正在加水,加入 240 L水  
  13. 注水线程正在加水,加入 260 L水  
  14. 注水线程正在加水,加入 280 L水  
  15. 注水线程正在加水,加入 300 L水  
  16. 注水线程正在加水,加入 320 L水  
  17. 注水线程正在加水,加入 340 L水  
  18. 注水线程正在加水,加入 360 L水  
  19. 注水线程正在加水,加入 380 L水  
  20. 注水线程正在加水,加入 400 L水  
  21. 注水线程正在加水,加入 420 L水  
  22. 注水线程正在加水,加入 440 L水  
  23. 注水线程正在加水,加入 460 L水  
  24. 注水线程正在加水,加入 480 L水  
  25. 注水线程正在加水,加入 500 L水  
  26. 注水线程水已加满!!,可以放水了......  
  27. 放水线程开始放水,放出 20 L水  
  28. 放水线程开始放水,放出 40 L水  
  29. 放水线程开始放水,放出 60 L水  
  30. 放水线程开始放水,放出 80 L水  
  31. 放水线程开始放水,放出 100 L水  
  32. 放水线程开始放水,放出 120 L水  
  33. 放水线程开始放水,放出 140 L水  
  34. 放水线程开始放水,放出 160 L水  
  35. 放水线程开始放水,放出 180 L水  
  36. 放水线程开始放水,放出 200 L水  
  37. 放水线程开始放水,放出 220 L水  
  38. 放水线程开始放水,放出 240 L水  
  39. 放水线程开始放水,放出 260 L水  
  40. 放水线程开始放水,放出 280 L水  
  41. 放水线程开始放水,放出 300 L水  
  42. 放水线程开始放水,放出 320 L水  
  43. 放水线程开始放水,放出 340 L水  
  44. 放水线程开始放水,放出 360 L水  
  45. 放水线程开始放水,放出 380 L水  
  46. 放水线程开始放水,放出 400 L水  
  47. 放水线程开始放水,放出 420 L水  
  48. 放水线程开始放水,放出 440 L水  
  49. 放水线程开始放水,放出 460 L水  
  50. 放水线程开始放水,放出 480 L水  
  51. 放水线程开始放水,放出 500 L水  
  52. 放水线程水已放完,可以加水了.....  
  53. 注水线程正在加水,加入 20 L水  
  54. 注水线程正在加水,加入 40 L水  
  55. 注水线程正在加水,加入 60 L水  
  56. 注水线程正在加水,加入 80 L水  
  57. 注水线程正在加水,加入 100 L水  
  58. 注水线程正在加水,加入 120 L水  
  59. 注水线程正在加水,加入 140 L水  
  60. 注水线程正在加水,加入 160 L水  
  61. 注水线程正在加水,加入 180 L水  
  62. 注水线程正在加水,加入 200 L水  
  63. 注水线程正在加水,加入 220 L水  
  64. 注水线程正在加水,加入 240 L水  
  65. 注水线程正在加水,加入 260 L水  
  66. 注水线程正在加水,加入 280 L水  
  67. 注水线程正在加水,加入 300 L水  
  68. 注水线程正在加水,加入 320 L水  
  69. 注水线程正在加水,加入 340 L水  
  70. 注水线程正在加水,加入 360 L水  
  71. 注水线程正在加水,加入 380 L水  
  72. 注水线程正在加水,加入 400 L水  
  73. 注水线程正在加水,加入 420 L水  
  74. 注水线程正在加水,加入 440 L水  
  75. 注水线程正在加水,加入 460 L水  
  76. 注水线程正在加水,加入 480 L水  
  77. 注水线程正在加水,加入 500 L水  
  78. 注水线程水已加满!!,可以放水了......  
  79. 放水线程开始放水,放出 20 L水  
  80. 放水线程开始放水,放出 40 L水  
  81. 放水线程开始放水,放出 60 L水  
  82. 放水线程开始放水,放出 80 L水  
  83. 放水线程开始放水,放出 100 L水  
  84. 放水线程开始放水,放出 120 L水  
  85. 放水线程开始放水,放出 140 L水  
  86. 放水线程开始放水,放出 160 L水  
  87. 放水线程开始放水,放出 180 L水  
  88. 放水线程开始放水,放出 200 L水  

猜你喜欢

转载自blog.csdn.net/sunming0129/article/details/79943995