java.lang.Thread.interrupt()是做什么的?
你能解释什么时候调用java.lang.Thread.interrupt()
吗?
Thread.interrupt()
设置目标线程的中断状态/标志。 然后,运行在该目标线程中的代码可以轮询中断状态并适当地处理它。 一些阻塞诸如Object.wait()
可能会立即消耗被中断的状态并引发适当的异常(通常是InterruptedException
)
Java中的中断不是先发制人的。 换句话说,两个线程必须配合才能正确处理中断。 如果目标线程不轮询中断状态,则中断被有效忽略。
轮询通过Thread.interrupted()
方法进行,该方法返回当前线程的中断状态并清除该中断标志。 通常这个线程可能会做一些事情,比如throw InterruptedException。
编辑(来自Thilo评论):一些API方法已经建立在中断处理。 这包括我的头顶。
-
Object.wait()/Thread.sleep()
- 大多数
java.util.concurrent
结构 - Java NIO(但不是java.io),它不使用
InterruptedException
,而是使用ClosedByInterruptException
。
编辑(从@托马斯色情的答案完全相同的问题完成)
线程中断是微调线程的温和方式。 它被用来给线程一个干净的退出的机会,而Thread.stop()
更像是用突击步枪射击线程。
什么是中断?
中断是一个线程的指示,它应该停止它正在做的事情,并做其他事情。 由程序员来决定线程是如何响应中断的,但线程终止是非常常见的。
它是如何实现的?
中断机制是使用一个称为中断状态的内部标志来实现的。 调用Thread.interrupt设置这个标志。 当一个线程通过调用静态方法Thread.interrupted检查中断时,中断状态被清除。 一个线程用来查询另一个线程的中断状态的非静态Thread.isInterrupted不会改变中断状态标志。
从Thread.interrupt()
API引用:
中断这个线程。 首先调用此线程的checkAccess方法,这可能会导致SecurityException被抛出。
如果该线程在Object类的wait(),wait(long)或wait(long,int)方法或join(),join ,sleep(long)或sleep(long,int)这个类的方法,那么它的中断状态将被清除,并且会收到一个InterruptedException异常。
如果此线程在可中断通道的I / O操作中被阻塞,则通道将被关闭,线程的中断状态将被设置,并且线程将收到ClosedByInterruptException。
如果这个线程在Selector中被阻塞,那么线程的中断状态将被设置,它将立即从选择操作中返回,可能有一个非零值,就像调用了选择器的唤醒方法一样。
如果以前的条件都不成立,那么这个线程的中断状态将被设置。
检查了解有关完整的理解:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
如果目标线程一直在等待(通过调用wait()
或其他一些基本上做同样事情的相关方法,如sleep()
),它将被中断,这意味着它停止等待它正在等待的内容而是接收InterruptedException。
这完全取决于线程本身(称为wait()
)的代码来决定在这种情况下做什么。 它不会自动终止线程。
它有时与终止标志组合使用。 当中断时,线程可以检查这个标志,然后关闭。 但是,这只是一个惯例。
为了完整性,除了其他的答案之外, 如果线程在阻塞Object.wait(..)
或Thread.sleep(..)
等之前被中断,这相当于在阻塞该方法之后立即中断如下例所示。
public class InterruptTest { public static void main(String[] args) { Thread.currentThread().interrupt(); printInterrupted(1); Object o = new Object(); try { synchronized (o) { printInterrupted(2); System.out.printf("A Time %d\n", System.currentTimeMillis()); o.wait(100); System.out.printf("B Time %d\n", System.currentTimeMillis()); } } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("C Time %d\n", System.currentTimeMillis()); printInterrupted(3); Thread.currentThread().interrupt(); printInterrupted(4); try { System.out.printf("D Time %d\n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("E Time %d\n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("F Time %d\n", System.currentTimeMillis()); printInterrupted(5); try { System.out.printf("G Time %d\n", System.currentTimeMillis()); Thread.sleep(100); System.out.printf("H Time %d\n", System.currentTimeMillis()); } catch (InterruptedException ie) { System.out.printf("WAS interrupted\n"); } System.out.printf("I Time %d\n", System.currentTimeMillis()); } static void printInterrupted(int n) { System.out.printf("(%d) Am I interrupted? %s\n", n, Thread.currentThread().isInterrupted() ? "Yes" : "No"); } }
输出:
$ javac InterruptTest.java $ java -classpath "." InterruptTest (1) Am I interrupted? Yes (2) Am I interrupted? Yes A Time 1399207408543 WAS interrupted C Time 1399207408543 (3) Am I interrupted? No (4) Am I interrupted? Yes D Time 1399207408544 WAS interrupted F Time 1399207408544 (5) Am I interrupted? No G Time 1399207408545 H Time 1399207408668 I Time 1399207408669
含义:如果你像下面那样循环,并且中断发生在控制离开Thread.sleep(..)
并且在循环周围的时刻,异常仍然会发生。 所以在线程被中断之后依靠InterruptedException被可靠地抛出是完全安全的 :
while (true) { try { Thread.sleep(10); } catch (InterruptedException ie) { break; } }
public void interrupt()
中断这个线程。
除非当前线程正在中断自己,这总是允许的,否则调用此线程的checkAccess方法,这可能会导致抛出SecurityException。
如果该线程在Object类的wait(),wait(long)或wait(long,int)方法或join(),join ,sleep(long)或sleep(long,int)这个类的方法,那么它的中断状态将被清除,并且会收到一个InterruptedException异常。
如果此线程在可中断通道的I / O操作中被阻塞,则通道将被关闭,线程的中断状态将被设置,并且线程将收到ClosedByInterruptException。
如果这个线程在Selector中被阻塞,那么线程的中断状态将被设置,它将立即从选择操作中返回,可能有一个非零值,就像调用了选择器的唤醒方法一样。
如果以前的条件都不成立,那么这个线程的中断状态将被设置。
中断不活动的线程不需要任何影响。
抛出:SecurityException – 如果当前线程无法修改此线程
Thread.interrupt()
将目标线程的中断状态/标志设置为true,当使用Thread.interrupted()
进行检查时,可以帮助停止无限的线程。 请参阅http://www.yegor256.com/2015/10/20/interrupted-exception.html
中断是一个线程的指示,它应该停止它正在做的事情,并做其他事情。 由程序员来决定线程是如何响应中断的,但线程终止是非常常见的。 非常好的参考: https : //docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
线程中断是基于标志中断状态 。 对于每个线程, 中断状态的默认值都设置为false 。 无论何时在线程上调用interrupt()方法,中断状态都将设置为true 。
- 如果中断状态=真(中断()已经调用线程),该特定的线程不能进入休眠状态。 如果在该线程中调用了睡眠中断异常,则抛出该异常。 再次抛出异常之后,标志被设置为false。
- 如果线程已经在休眠并且调用了interrupt() ,那么线程将从睡眠状态退出并抛出中断异常。