第二部分 线程的等待和唤醒

文章出自:http://blog.youkuaiyun.com/cuiran/article/details/6133745

从这个图中可以看出,等待状态是一种特殊的状态。使线程陷入等待实际上是暂时剥夺线程当前拥有的CPU时间片和获取CPU时间片的资格,使其返回到就绪状态。除非被唤醒,否则等待时间已满,该线程将一直等待。不会被JVM线程调度器选中并赋予CPU时间片。处于等待的线程一旦恢复执行,与其他处于就绪状态被线程调度器选中的线程不同,将从上次结束执行的断点处开始执行,而非从头开始。

 使线程中断运行,返回就绪状态的手段是调用java.lang.Object对象的wait()方法;唤醒处于等待状态的线程的手段是调用java.lang.Object对象的notify()方法

为了加深理解,下面就通过具体例子来说明线程等待和唤醒

第一个:

通过继承Thread来创建子线程。

[java]  view plain copy
  1. /** 
  2.  * NotifyWaitingThread.java 
  3.  * 版权所有(C) 2011 cuiran2001@163.com 
  4.  * 创建:崔冉  2011-1-11 上午11:24:33 
  5.  */  
  6.   
  7. package com.cayden.thread;  
  8.   
  9. /** 
  10.  * @author 崔冉 
  11.  * @version 1.0.0 
  12.  * @desc 
  13.  */  
  14. public class NotifyWaitingThread {  
  15.   
  16.     /** 
  17.      * @param args 
  18.      */  
  19.     public static void main(String[] args) throws InterruptedException{  
  20.         // TODO Auto-generated method stub  
  21.         MyThread [] threads=new MyThread[3];  
  22.         for(int i=0;i<3;i++){  
  23.             threads[i]=new MyThread();  
  24.             threads[i].no=i;  
  25.             threads[i].setDaemon(true);  
  26.             threads[i].start();  
  27.         }  
  28.         Thread.sleep(5000);  
  29.         for(int i=0;i<3;i++){  
  30.             synchronized(threads[i]){  
  31.                 threads[i].notify();  
  32.             }  
  33.         }  
  34.     }  
  35.   
  36. }  
  37. class MyThread extends Thread{  
  38.       
  39.     public int no=0;  
  40.     public void run(){  
  41.         System.out.println("第"+this.no+"个线程开始等待5分钟");  
  42.         try{  
  43.             synchronized(this){  
  44.                 this.wait(5*60*1000);  
  45.             }  
  46.         }catch (InterruptedException e) {  
  47.             // TODO: handle exception  
  48.             e.printStackTrace();  
  49.         }  
  50.         System.out.println("第"+this.no+"个线程被唤醒");  
  51.     }  
  52.       
  53.       
  54. }  

运行效果如下:

[java]  view plain copy
  1. 0个线程开始等待5分钟  
  2. 2个线程开始等待5分钟  
  3. 1个线程开始等待5分钟  
  4. 0个线程被唤醒  
  5. 2个线程被唤醒  
  6. 1个线程被唤醒  

第二个:

通过实现Runnable接口来创建子线程

[java]  view plain copy
  1. /** 
  2.  * NotifyWaitingThreadWithRunnable.java 
  3.  * 版权所有(C) 2011 cuiran2001@163.com 
  4.  * 创建:崔冉  2011-1-11 下午01:48:04 
  5.  */  
  6.   
  7. package com.cayden.thread;  
  8.   
  9. /** 
  10.  * @author 崔冉 
  11.  * @version 1.0.0 
  12.  * @desc 
  13.  */  
  14. public class NotifyWaitingThreadWithRunnable {  
  15.   
  16.     /** 
  17.      * @param args 
  18.      */  
  19.     public static void main(String[] args) throws InterruptedException{  
  20.         // TODO Auto-generated method stub  
  21.         Runner[] runners=new Runner[3];  
  22.         Thread[] threads=new Thread[3];  
  23.         for(int i=0;i<3;i++){  
  24.             runners[i]=new Runner(i);  
  25.             threads[i]=new Thread(runners[i]);  
  26.             threads[i].setDaemon(true);  
  27.             threads[i].start();  
  28.         }  
  29.         Thread.sleep(500);  
  30.         for(int i=0;i<3;i++){  
  31.             synchronized (runners[i]) {  
  32.                 runners[i].notify();  
  33.             }  
  34.         }  
  35.     }  
  36.   
  37. }  
  38. class Runner implements Runnable{  
  39.   
  40.     private int no=0;  
  41.     public Runner(int no){  
  42.         this.no=no;  
  43.     }  
  44.       
  45.     @Override  
  46.     public void run() {  
  47.         // TODO Auto-generated method stub  
  48.         System.out.println("第"+this.no+"个线程开始等待5分钟");  
  49.         try{  
  50.             synchronized(this){  
  51.                 this.wait(5*60*1000);  
  52.             }  
  53.         }catch (InterruptedException e) {  
  54.             // TODO: handle exception  
  55.             e.printStackTrace();  
  56.         }  
  57.         System.out.println("第"+this.no+"个线程被唤醒");  
  58.     }  
  59.       
  60. }  

运行效果如下:

[java]  view plain copy
  1. 0个线程开始等待5分钟  
  2. 2个线程开始等待5分钟  
  3. 1个线程开始等待5分钟  
  4. 1个线程被唤醒  
  5. 0个线程被唤醒  
  6. 2个线程被唤醒  

第三个:

通过实现Runnable,又通过Object对象的notifyAll()方法一次性唤醒多个同一个对象创造的线程。

[java]  view plain copy
  1. /** 
  2.  * NotifyWaitingThreadWithSameRunnable.java 
  3.  * 版权所有(C) 2011 cuiran2001@163.com 
  4.  * 创建:崔冉  2011-1-11 下午02:34:01 
  5.  */  
  6.   
  7. package com.cayden.thread;  
  8.   
  9. /** 
  10.  * @author 崔冉 
  11.  * @version 1.0.0 
  12.  * @desc 
  13.  */  
  14. public class NotifyWaitingThreadWithSameRunnable {  
  15.   
  16.     /** 
  17.      * @param args 
  18.      */  
  19.     public static void main(String[] args) throws InterruptedException{  
  20.         // TODO Auto-generated method stub  
  21.         SameRunner runner=new SameRunner();  
  22.         Thread[] threads=new Thread[3];  
  23.         for(int i=0;i<3;i++){  
  24.             threads[i]=new Thread(runner);  
  25.             threads[i].setDaemon(true);  
  26.             threads[i].start();  
  27.         }  
  28.         Thread.sleep(500);  
  29.         synchronized(runner){  
  30.             runner.notifyAll();  
  31. //          runner.notify(); //被唤醒的只有一个线程  
  32.         }  
  33.     }  
  34.   
  35. }  
  36. class SameRunner implements Runnable{  
  37.   
  38.     @Override  
  39.     public void run() {  
  40.         // TODO Auto-generated method stub  
  41.         System.out.println("线程开始等待5分钟");  
  42.         try{  
  43.             synchronized(this){  
  44.                 this.wait(5*60*1000);  
  45.             }  
  46.         }catch (InterruptedException e) {  
  47.             // TODO: handle exception  
  48.             e.printStackTrace();  
  49.         }  
  50.         System.out.println("线程被唤醒");  
  51.     }  
  52.       
  53. }  

运行效果如下:

[java]  view plain copy
  1. 线程开始等待5分钟  
  2. 线程开始等待5分钟  
  3. 线程开始等待5分钟  
  4. 线程被唤醒  
  5. 线程被唤醒  
  6. 线程被唤醒  

总结:1).利用Thread.sleep().使线程开始休眠指定的时间,以便让各个子线程进入等待状态。

      2).synchronized同步锁的使用。这一块在后面文章中会加以解说。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值