您能解释一下java.lang.Thread.interrupt()
调用时会发生什么吗?
您能解释一下java.lang.Thread.interrupt()
调用时会发生什么吗?
Answers:
Thread.interrupt()
设置目标线程的中断状态/标志。然后在该目标线程中运行的代码可以轮询中断状态并适当地处理它。某些诸如此类的方法Object.wait()
可能会立即消耗中断状态并抛出适当的异常(通常为InterruptedException
)
Java中的中断不是抢先的。换句话说,两个线程必须配合才能正确处理中断。如果目标线程未轮询中断状态,则该中断将被有效忽略。
通过Thread.interrupted()
返回当前线程的中断状态并清除该中断标志的方法进行轮询。通常,线程然后可能会执行某些操作,例如throw InterruptedException。
编辑(来自Thilo注释):一些API方法已内置中断处理。在我的头上包括。
Object.wait()
,Thread.sleep()
和Thread.join()
java.util.concurrent
结构InterruptedException
,而是使用ClosedByInterruptException
。编辑(来自@ thomas-pornin对完全相同的问题的回答,以确保完整性)
线程中断是微调线程的一种温和方法。它用于使线程有机会干净地退出,而不是Thread.stop()
像用突击步枪射击线程一样。
什么是中断?
中断表明线程应该停止正在执行的操作并执行其他操作。完全由程序员决定线程如何响应中断,但是线程终止是很常见的。
如何实施?
中断机制是使用内部标志(称为中断状态)实现的。调用Thread.interrupt设置此标志。当线程通过调用静态方法Thread.interrupted检查中断时,将清除中断状态。一个线程用于查询另一线程的中断状态的非静态Thread.isInterrupted不会更改中断状态标志。
中断此线程。首先,调用此线程的checkAccess方法,这可能会引发SecurityException。
如果在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法时阻塞了此线程,sleep(long)或sleep(long,int)此类的方法,则其中断状态将被清除,并将收到InterruptedException。
如果此线程在可中断通道的I / O操作中被阻止,则该通道将被关闭,线程的中断状态将被设置,并且该线程将收到ClosedByInterruptException。
如果此线程在选择器中被阻塞,则该线程的中断状态将被设置,并且它将立即从选择操作中返回,可能具有非零值,就像调用选择器的唤醒方法一样。
如果以上条件均不成立,则将设置该线程的中断状态。
查看此内容,以完全了解相同内容:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
为了完整起见,除了其他的答案,如果线程被中断就可以了块之前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;
}
}
Thread.interrupt()
将目标线程的中断状态/标志设置为true,这在使用进行检查时Thread.interrupted()
可以帮助停止循环线程。请参阅http://www.yegor256.com/2015/10/20/interrupted-exception.html
公共无效中断()
中断此线程。
除非总是允许当前线程中断自身,否则将一直调用此线程的checkAccess方法,这可能会引发SecurityException。
如果在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long,int)方法时阻塞了此线程,sleep(long)或sleep(long,int)此类的方法,则其中断状态将被清除,并将收到InterruptedException。
如果此线程在可中断通道的I / O操作中被阻止,则该通道将被关闭,线程的中断状态将被设置,并且该线程将收到ClosedByInterruptException。
如果此线程在选择器中被阻塞,则该线程的中断状态将被设置,并且它将立即从选择操作中返回,可能具有非零值,就像调用选择器的唤醒方法一样。
如果上述条件均不成立,则将设置该线程的中断状态。
中断未激活的线程不会产生任何效果。
抛出:SecurityException-如果当前线程无法修改此线程
中断表明线程应该停止正在执行的操作并执行其他操作。完全由程序员决定线程如何响应中断,但是终止线程是很常见的。一个很好的参考:https : //docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Thread.interrupt()方法设置内部“中断状态”标志。通常,该标志由Thread.interrupted()方法检查。
按照约定,通过InterruptedException存在的任何方法都必须清除中断状态标志。