多线程例子:wait与notify、sleep

来源:互联网 发布:charindex函数 sql 编辑:程序博客网 时间:2024/05/29 07:29
Java代码  收藏代码
  1. package sure;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5.   
  6.   
  7. public class Test {  
  8.   
  9.     private static Logger log = LoggerFactory.getLogger(Test.class);  
  10.       
  11.     public static void main(String[] args) throws Exception {    
  12.         final Object lock="";    
  13.         Thread t1=new Thread(){    
  14.             public void run(){    
  15.                 try {    
  16.                     log.info("t1 wait begin");    
  17.                     synchronized (lock) {    
  18.                         log.info("t1 get lock, wait begin");  
  19.                         lock.wait();    
  20.                         log.info("t1 wait end,release lock");  
  21.                         lock.notifyAll();  
  22.                     }    
  23.                     log.info("t1  wait end");    
  24.                 } catch (InterruptedException e) {    
  25.                     e.printStackTrace();    
  26.                 }    
  27.             }    
  28.         };    
  29.             
  30.         t1.start();    
  31.         log.info("t1 start and sleep");  
  32.         for(int i=0;i<10000001;i++){  
  33.             if(i==10000000)  
  34.                 log.info("i end");  
  35.         }  
  36.         Thread.sleep(5000);    
  37.         log.info("sleep(5000) end");  
  38.             
  39.         log.info("main lock begin");    
  40.         synchronized (lock) {  
  41.             log.info("main get lock");  
  42.             lock.notify();  
  43.             log.info("notify");  
  44.             Thread.sleep(10000);   
  45.             log.info("sleep 10000 end");  
  46.             log.info("main wait begin ");    
  47.             lock.wait();    
  48.             log.info("main wait end");    
  49.         }    
  50.         log.info("main lock end");    
  51.     }    
  52. }  


日志信息如下: 
Java代码  收藏代码
  1. 2011-11-09 15:44:05,968 INFO [sure.Test] - t1 start and sleep  
  2. 2011-11-09 15:44:05,968 INFO [sure.Test] - t1 wait begin  
  3. 2011-11-09 15:44:05,968 INFO [sure.Test] - t1 get lock, wait begin  
  4. 2011-11-09 15:44:05,984 INFO [sure.Test] - i end  
  5. 2011-11-09 15:44:10,984 INFO [sure.Test] - sleep(5000) end  
  6. 2011-11-09 15:44:10,984 INFO [sure.Test] - main lock begin  
  7. 2011-11-09 15:44:10,984 INFO [sure.Test] - main get lock  
  8. 2011-11-09 15:44:10,984 INFO [sure.Test] - notify  
  9. 2011-11-09 15:44:20,984 INFO [sure.Test] - sleep 10000 end  
  10. 2011-11-09 15:44:20,984 INFO [sure.Test] - main wait begin   
  11. 2011-11-09 15:44:20,984 INFO [sure.Test] - t1 wait end,release lock  
  12. 2011-11-09 15:44:20,984 INFO [sure.Test] - t1  wait end  
  13. 2011-11-09 15:44:20,984 INFO [sure.Test] - main wait end  
  14. 2011-11-09 15:44:20,984 INFO [sure.Test] - main lock end  


wait,notify,notifyAll必须在当前线程获得监视器时才能调用,即这些方法必须在同步块中才能调用。 

被阻塞的线程在被notify之后,并不是马上可以执行,而是“可执行”,要到获得锁之后才能真正开始执行。 

从这个例子进行各种修改可以用来加深对线程的理解。 
Java代码  收藏代码
  1. package sure;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5.   
  6.   
  7. public class Test {  
  8.   
  9.     private static Logger log = LoggerFactory.getLogger(Test.class);  
  10.       
  11.     public static void main(String[] args) throws Exception {    
  12.         final Object lock="";    
  13.         Thread t1=new Thread(){    
  14.             public void run(){    
  15.                 try {    
  16.                     log.info("t1 wait begin");    
  17.                     synchronized (lock) {    
  18.                         log.info("t1 get lock, wait begin");  
  19.                         Thread.sleep(5000);  
  20.                         log.info("sleep end");  
  21.                         lock.wait();    
  22.                         log.info("t1 wait end,release lock");  
  23.                         lock.notifyAll();  
  24.                     }    
  25.                     Thread.sleep(5000);  
  26.                     log.info("t1  wait end");    
  27.                 } catch (InterruptedException e) {    
  28.                     e.printStackTrace();    
  29.                 }    
  30.             }    
  31.         };    
  32.             
  33.         t1.start();    
  34.         log.info("t1 start and sleep");  
  35.             
  36.         log.info("main lock begin");    
  37.         synchronized (lock) {  
  38.             log.info("main get lock");  
  39.             lock.notify();  
  40.             log.info("notify");  
  41.             Thread.sleep(10000);   
  42.             log.info("sleep 10000 end");  
  43.             log.info("main wait begin ");    
  44.             lock.wait();    
  45.             log.info("main wait end");    
  46.         }    
  47.         log.info("main lock end");    
  48.          
  49.     }    
  50.   
  51. }  

日志为: 
Java代码  收藏代码
  1. 2011-11-09 16:55:19,031 INFO [sure.Test] - t1 start and sleep  
  2. 2011-11-09 16:55:19,031 INFO [sure.Test] - main lock begin  
  3. 2011-11-09 16:55:19,031 INFO [sure.Test] - main get lock  
  4. 2011-11-09 16:55:19,031 INFO [sure.Test] - notify  
  5. 2011-11-09 16:55:19,031 INFO [sure.Test] - t1 wait begin  
  6. 2011-11-09 16:55:29,031 INFO [sure.Test] - sleep 10000 end  
  7. 2011-11-09 16:55:29,031 INFO [sure.Test] - main wait begin   
  8. 2011-11-09 16:55:29,031 INFO [sure.Test] - t1 get lock, wait begin  
  9. 2011-11-09 16:55:34,031 INFO [sure.Test] - sleep end  

然后两个线程都会被阻塞,造成死锁。 
这个例子进一步说明了同步的用法,另外也表明了Thread.sleep是针对当前运行线程的。 

有趣的是,同样是这个代码,在另一种情况下会出现这种情况: 
Java代码  收藏代码
  1. 2011-11-09 22:06:05,930 INFO [sure.Test] - t1 start and sleep  
  2. 2011-11-09 22:06:05,930 INFO [sure.Test] - t1 wait begin  
  3. 2011-11-09 22:06:05,930 INFO [sure.Test] - main lock begin  
  4. 2011-11-09 22:06:05,930 INFO [sure.Test] - t1 get lock, wait begin  
  5. 2011-11-09 22:06:10,930 INFO [sure.Test] - sleep end  
  6. 2011-11-09 22:06:10,930 INFO [sure.Test] - main get lock  
  7. 2011-11-09 22:06:10,930 INFO [sure.Test] - notify  
  8. 2011-11-09 22:06:20,930 INFO [sure.Test] - sleep 10000 end  
  9. 2011-11-09 22:06:20,930 INFO [sure.Test] - main wait begin   
  10. 2011-11-09 22:06:20,930 INFO [sure.Test] - t1 wait end,release lock  
  11. 2011-11-09 22:06:20,930 INFO [sure.Test] - main wait end  
  12. 2011-11-09 22:06:20,930 INFO [sure.Test] - main lock end  
  13. 2011-11-09 22:06:25,930 INFO [sure.Test] - t1  wait end  

这种情况不会造成死锁阻塞。 
由于这两个线程都谁都可能先进入同步块中,所以就造成了两个截然不同的情况。但是上面第一种情况就肯定是子进程先进入同步块,因为main进程用sleep拖延了。
阅读全文
0 0
原创粉丝点击