与java中线程状态相关的interrupt()方法的精确行为
Posted
技术标签:
【中文标题】与java中线程状态相关的interrupt()方法的精确行为【英文标题】:precise behaviour of interrupt() method with respective to thread states in java 【发布时间】:2016-10-27 20:04:30 【问题描述】:我已经阅读了下面的帖子
What does java.lang.Thread.interrupt() do? 但我没能完全正确
我引用@Mike_q 对上述问题的回答如下
Thread.interrupt() 设置目标线程的中断状态/标志。然后在该目标线程中运行的代码可以轮询中断状态并适当地处理它。一些阻塞的方法如 Object.wait() 可能会立即消耗中断状态并抛出适当的异常(通常是 InterruptedException)
它说当对象处于 WAITING 时它可以消耗中断状态,那么当它处于 BLOCKED 状态等待对象的锁定时会发生什么......?
我已经在下面尝试了这种情况,代码是
在 X:t2 被阻止
public class interruptsyc
static Object resource = new Object();
public static void main(String []args)
System.out.println("started main");
Thread1 t1=new Thread1("thread 1");
t1.start();
delay(1000);
Thread2 t2 =new Thread2("thread 2");
t2.start();
delay(1000);
t2.interrupt(); // X: at this point t2 is in blocked state waiting for resource's lock
System.out.println(t2.getName()+t2.interrupted());
delay(1000);
System.out.println("end main");
static void delay(long n)
try
Thread.sleep(n);
catch(InterruptedException ex)
System.out.println(Thread.currentThread().getName()+Thread.interrupted());
ex.printStackTrace();
static class Thread1 extends Thread
Thread1(String name)
setName(name);
public void run()
synchronized(resource)
System.out.println("start 1");
delay(6000);
System.out.println("end 1");
static class Thread2 extends Thread
Thread2(String name )
setName(name);
public void run()
synchronized(resource)
System.out.println("start 2");
delay(2000);
System.out.println("end 2");
输出低于
started main
start 1
false
end main
end 1
start 2
thread 2false
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at interruptsyc.delay(interruptsyc.java:25)
at interruptsyc$Thread2.run(interruptsyc.java:59)
end 2
好像调用了InterruptedException,后面调用sleep方法的时候……这是为什么……?
再一次,我从这里所说的内容中不太明白什么是轮询
通过 Thread.interrupted() 方法进行轮询,该方法返回当前线程的中断状态并清除该中断标志。通常线程可能会做一些事情,比如抛出 InterruptedException。
每当我在上面的代码中调用 Thread2.interrupted() 方法时,它都会返回 false (当我在 t2.interrupt 之后和 catch 块中调用时)
【问题讨论】:
【参考方案1】:好像调用了InterruptedException,后面调用sleep方法的时候……这是为什么……?
因为阻塞/休眠方法不会立即阻塞。他们首先检查线程是否被中断,如果已经被中断,则立即抛出 InterruptedException,以便线程尽快停止。
每当我在上面的代码中调用 Thread2.interrupted() 方法时,它都会返回 false
因为当阻塞/休眠方法抛出 InterruptedException 时,它们也会清除中断标志。
这是在Thread.sleep()的javadoc中:
抛出 InterruptedException - 如果任何线程中断了当前线程。抛出该异常时清除当前线程的中断状态。
【讨论】:
但是上面代码中的t2.interrupt()此时还没有抛出中断异常并且中断标志仍然有效 不知道你在问什么,但我认为你对t2.interrupted()
的电话引起了一些混乱。 ìinterrupted() 是一个静态 方法。它检查当前线程是否被中断。所以你不应该把它叫做t2.interrupted()
,而应该叫做Thread.interrupted()
。要知道在另一个线程被中断,无需清除中断标志,使用t2.isInterrupted()
。我重写了您的代码以产生更有意义的输出:gist.github.com/jnizet/1e983582a5f5d8b1e9b6a81ed2a731e9以上是关于与java中线程状态相关的interrupt()方法的精确行为的主要内容,如果未能解决你的问题,请参考以下文章