wait时间到或被中断唤醒时,仍然需要等待获取锁。
import java.io.IOException;public class Demo { /** * @param args * @throws IOException * @throws InterruptedException * @throws ClassNotFoundException */ public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { T1 t1 = new T1(); T2 t2 = new T2(t1); t1.start(); t2.start(); } static Integer i = 0; static class T1 extends Thread { public void run() { synchronized (i) { System.out.println("T1-在syn里"); try { i.wait(50L);//验证表明:wait时间到或被中断唤醒,不会继续执行或者跳到catch里 // (因为根本得不到执行,根本没法抛出InterruptedException,所以即使catch块放在syschronized外也一样 ), //而是还需要等待获得锁。 //如果wait时间到或被中断唤醒,而T2还在syn里,那么T1还是会等待。 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("结束wait-T1"); System.out.println("T1-在syn里"); try { Thread.sleep(10000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("T1-在syn里"); } System.out.println("离开syn-T1"); } } static class T2 extends Thread { Thread t1; public T2(Thread t1){ this.t1 = t1; } public void run() { synchronized (i) { System.out.println("T2-在syn里"); try { t1.interrupt(); Thread.sleep(10000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("T2-还在syn里"); } System.out.println("T2-离开syn"); } }}?
验证表明:wait时间到或被中断唤醒,不一定会继续执行或者跳到catch里,而是还需要等待获得锁。
?????????????? 如果wait时间到或被中断唤醒,而T2还在syn里,那么T1还是会等待。
?
另外,Thread.interrupt()唤醒线程之后,其实是设置了Thead的中断状态,后续任何时候,当该线程尝试wait,join,sleep时,中断状态都会起作用,使得Thread被中断,wait/join/sleep方法会抛出中断异常(wait需要获取锁后才能继续抛出异常)。这点javadoc有说明。
?
?
_____________________________________________________________________________
?
?
?
package com.atell;import java.io.IOException;public class Demo { public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { T1 t1 = new T1(); T2 t2 = new T2(t1); t1.start(); t2.start(); } static Integer i = 0; static class T1 extends Thread { public void run() { synchronized (i) { System.out.println("T1-syn-start"); try { i.wait();// 可以被notify唤醒,也可以被interrupt唤醒,取决于T2中哪个操作先执行 } catch (InterruptedException e) { System.out.println("在wait时被中断"); } try { Thread.sleep(2000L); } catch (InterruptedException e) { System.out.println("在sleep时被中断"); } System.out.println("T1-syn-end"); } System.out.println("离开syn-T1"); } } static class T2 extends Thread { Thread t1; public T2(Thread t1){ this.t1 = t1; } public void run() { synchronized (i) { System.out.println("T2-syn-start"); //(1)如果先interrupt再notify,那么i.wait会因为interrupt而醒过来,notify则不对它起作用(如果此时Monitor的等待队列有其他线程,则notify必须去唤醒其他线程,不能虚发- Java语言规范17.8.4最后一句明确提到。)。 //t1.interrupt(); //i.notify(); //(2)如果先notify再interrupt,那么i.wait会因为notify而醒过来,interrupt则对T1后续的sleep起作用。 i.notify(); t1.interrupt(); System.out.println("T2-syn-end"); } System.out.println("T2-离开syn"); } }}?
验证表明:wait可以被notify唤醒,也可以被interrupt唤醒,取决于哪个操作先执行
(以上是看《Java语言规范17.8节》之后的结论)
?