当调用java.lang.Thread.interrupt()
时,它会将线程的中断状态设置为“中断”。
当调用java.lang.Thread.interrupt()
时,它会将线程的中断状态设置为“中断”。
Thread.interrupt()
方法会设置目标线程的中断状态/标志。然后在该目标线程中运行的代码可以轮询中断状态并适当地处理它。一些阻塞的方法,例如Object.wait()
可能会立即消耗中断状态并抛出适当的异常(通常是InterruptedException
)。
Java中的中断不是抢占式的。换句话说,为了正确处理中断,两个线程都必须合作。如果目标线程没有轮询中断状态,则中断实际上被忽略。
通过Thread.interrupted()
方法进行轮询,该方法返回当前线程的中断状态并清除该中断标志。通常,线程可能会执行某些操作,如抛出InterruptedException。
编辑(来自Thilo评论):一些API方法具有内置的中断处理功能。我能想到的包括:
Object.wait()
,Thread.sleep()
和Thread.join()
java.util.concurrent
结构InterruptedException
,而是使用ClosedByInterruptException
。编辑(来自@thomas-pornin对exactly same question的回答,以保证完整性)
线程中断是一种温和的方式来促使线程退出。它被用于给线程一个机会以“干净”的方式退出,而不像使用Thread.stop()
那样像用突击步枪射击线程。
什么是中断?
中断是对线程的指示,告诉它应该停止正在进行的工作并做其他事情。由程序员决定线程如何响应中断,但通常线程会终止。
它是如何实现的?
中断此线程。首先调用此线程的checkAccess方法,可能会导致抛出SecurityException异常。中断机制使用一个称为中断状态的内部标志来实现。调用Thread.interrupt设置此标志。当线程通过调用静态方法Thread.interrupted检查中断时,中断状态将被清除。非静态Thread.isInterrupted用于查询另一个线程的中断状态,不会更改中断状态标志。
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;
}
}
线程中断基于标志中断状态。 每个线程的中断状态默认值设置为false。 每当在线程上调用interrupt()方法时,中断状态就被设置为true。
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
Thread.interrupt()方法设置内部的“中断状态”标志。通常,该标志由Thread.interrupted()方法检查。
按照惯例,通过InterruptedException存在的任何方法都必须清除中断状态标志。
我想在以上答案中添加一两个内容。
需要记住的一件事是,调用中断方法并不总是会导致 InterruptedException
。因此,实现代码应定期检查中断状态并采取适当的措施。
Thread.currentThread().isInterrupted()
也可以用于检查线程的中断状态。与 Thread.interrupted()
方法不同,它不会清除中断状态。
public void interrupt()
中断此线程。
除非当前线程正在中断自己(这始终被允许),否则将调用此线程的checkAccess方法,这可能导致抛出SecurityException异常。
如果此线程在Object类的wait()、wait(long)或wait(long, int)方法,或者在该类的join()、join(long)、join(long, int)、sleep(long)或sleep(long, int)方法的调用中被阻塞,则它的中断状态将被清除,并且它将收到InterruptedException异常。
如果此线程在可中断通道上的I/O操作中被阻塞,则该通道将关闭,线程的中断状态将被设置,该线程将收到ClosedByInterruptException异常。
如果此线程在Selector中被阻塞,则线程的中断状态将被设置,并且它将立即从选择操作中返回,可能带有一个非零值,就像调用选择器的wake-up方法一样。
如果没有任何先前的情况成立,则将设置此线程的中断状态。
中断不活动的线程不必有任何效果。
抛出: SecurityException - 如果当前线程无法修改此线程