wait时间到或被中断唤醒时,仍然需要等待获取锁。

Java代码   收藏代码
  1. import java.io.IOException;  
  2.   
  3. public class Demo {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      * @throws IOException 
  8.      * @throws InterruptedException 
  9.      * @throws ClassNotFoundException 
  10.      */  
  11.     public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {  
  12.           
  13.         T1 t1 = new T1();  
  14.         T2 t2 = new T2(t1);  
  15.         t1.start();  
  16.         t2.start();  
  17.           
  18.     }  
  19.   
  20.   
  21.     static Integer i = 0;  
  22.   
  23.     static class T1 extends Thread {  
  24.   
  25.         public void run() {  
  26.   
  27.             synchronized (i) {  
  28.                 System.out.println("T1-在syn里");  
  29.                 try {  
  30.                     i.wait(50L);//验证表明:wait时间到或被中断唤醒,不会继续执行或者跳到catch里  
  31.                                 // (因为根本得不到执行,根本没法抛出InterruptedException,所以即使catch块放在syschronized外也一样 ),  
  32.                                 //而是还需要等待获得锁。  
  33.                                 //如果wait时间到或被中断唤醒,而T2还在syn里,那么T1还是会等待。  
  34.                 } catch (InterruptedException e) {  
  35.                     e.printStackTrace();  
  36.                 }  
  37.                 System.out.println("结束wait-T1");  
  38.                 System.out.println("T1-在syn里");  
  39.                 try {  
  40.                     Thread.sleep(10000L);  
  41.                 } catch (InterruptedException e) {  
  42.                     e.printStackTrace();  
  43.                 }  
  44.                 System.out.println("T1-在syn里");  
  45.             }  
  46.             System.out.println("离开syn-T1");  
  47.   
  48.         }  
  49.     }  
  50.       
  51.   
  52.     static class T2 extends Thread {  
  53.   
  54.         Thread t1;  
  55.         public T2(Thread t1){  
  56.             this.t1 = t1;  
  57.         }  
  58.           
  59.         public void run() {  
  60.             synchronized (i) {  
  61.                 System.out.println("T2-在syn里");  
  62.                 try {  
  63.                     t1.interrupt();  
  64.                     Thread.sleep(10000L);  
  65.                 } catch (InterruptedException e) {  
  66.                     e.printStackTrace();  
  67.                 }  
  68.                 System.out.println("T2-还在syn里");  
  69.             }  
  70.             System.out.println("T2-离开syn");  
  71.   
  72.         }  
  73.     }  
  74. }  

 

验证表明:wait时间到或被中断唤醒,不一定会继续执行或者跳到catch里,而是还需要等待获得锁。
               如果wait时间到或被中断唤醒,而T2还在syn里,那么T1还是会等待。

 

另外,Thread.interrupt()唤醒线程之后,其实是设置了Thead的中断状态,后续任何时候,当该线程尝试wait,join,sleep时,中断状态都会起作用,使得Thread被中断,wait/join/sleep方法会抛出中断异常(wait需要获取锁后才能继续抛出异常)。这点javadoc有说明。

 

 

_____________________________________________________________________________

 

 

 

Java代码   收藏代码
  1. package com.atell;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. public class Demo {  
  6.   
  7.     public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {  
  8.   
  9.         T1 t1 = new T1();  
  10.         T2 t2 = new T2(t1);  
  11.         t1.start();  
  12.         t2.start();  
  13.   
  14.     }  
  15.   
  16.     static Integer i = 0;  
  17.   
  18.     static class T1 extends Thread {  
  19.   
  20.         public void run() {  
  21.   
  22.             synchronized (i) {  
  23.                 System.out.println("T1-syn-start");  
  24.                 try {  
  25.                     i.wait();// 可以被notify唤醒,也可以被interrupt唤醒,取决于T2中哪个操作先执行  
  26.                 } catch (InterruptedException e) {  
  27.                     System.out.println("在wait时被中断");  
  28.                 }  
  29.                 try {  
  30.                     Thread.sleep(2000L);  
  31.                 } catch (InterruptedException e) {  
  32.                     System.out.println("在sleep时被中断");  
  33.                 }  
  34.                 System.out.println("T1-syn-end");  
  35.             }  
  36.             System.out.println("离开syn-T1");  
  37.   
  38.         }  
  39.     }  
  40.   
  41.     static class T2 extends Thread {  
  42.   
  43.         Thread t1;  
  44.   
  45.         public T2(Thread t1){  
  46.             this.t1 = t1;  
  47.         }  
  48.   
  49.         public void run() {  
  50.             synchronized (i) {  
  51.                 System.out.println("T2-syn-start");  
  52.                 //(1)如果先interrupt再notify,那么i.wait会因为interrupt而醒过来,notify则不对它起作用(如果此时Monitor的等待队列有其他线程,则notify必须去唤醒其他线程,不能虚发- Java语言规范17.8.4最后一句明确提到。)。  
  53.                 //t1.interrupt();  
  54.                 //i.notify();  
  55.                 //(2)如果先notify再interrupt,那么i.wait会因为notify而醒过来,interrupt则对T1后续的sleep起作用。  
  56.                 i.notify();  
  57.                 t1.interrupt();  
  58.                 System.out.println("T2-syn-end");  
  59.             }  
  60.             System.out.println("T2-离开syn");  
  61.   
  62.         }  
  63.     }  
  64. }  

 

验证表明:wait可以被notify唤醒,也可以被interrupt唤醒,取决于哪个操作先执行

(以上是看《Java语言规范17.8节》之后的结论)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值