你能解释一下调用java.lang.Thread.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。
如果这个线程在选择器中被阻塞,那么线程的中断状态将被设置,并且它将立即从选择操作中返回,可能是一个非零值,就像调用选择器的唤醒方法一样。
如果以上条件都不满足,则该线程的中断状态将被设置。
中断一个不活跃的线程不会有任何影响。
抛出: 如果当前线程不能修改该线程,则返回SecurityException
其他回答
线程中断基于标志中断状态。 对于每个线程,中断状态的默认值设置为false。 每当在线程上调用interrupt()方法时,中断状态被设置为true。
如果中断状态= true (interrupt()已经在线程上调用), 这个特定的线程不能进入睡眠状态。如果在该线程上调用sleep,则抛出中断异常。再次抛出异常后,标志被设置为false。 如果线程已经处于睡眠状态,并且调用interrupt(),线程将跳出睡眠状态并抛出中断的Exception。
thread. interrupt()设置目标线程的中断状态/标志。然后在目标线程中运行的代码可以轮询中断状态并适当地处理它。一些阻塞的方法,如Object.wait()可能会立即使用中断状态并抛出适当的异常(通常是InterruptedException)
Java中的中断不是先发制人的。换句话说,两个线程必须合作才能正确地处理中断。如果目标线程没有轮询中断状态,中断将被有效地忽略。
轮询通过thread .interrupted()方法进行,该方法返回当前线程的中断状态并清除中断标志。通常,线程可能会做一些事情,例如抛出InterruptedException。
EDIT(来自Thilo评论):一些API方法内置了中断处理。在我的头顶,这包括。
Object.wait(), Thread.sleep()和Thread.join() 大多数java.util.concurrent结构 Java NIO(但不是Java .io),它不使用InterruptedException,而是使用ClosedByInterruptException。
编辑(来自@thomas-pornin对完全相同问题的回答)
线程中断是轻推线程的一种温和方式。它用于给线程一个干净地退出的机会,而不是thread .stop(),后者更像是用突击步枪射击线程。
为了完整起见,除了其他答案外,如果线程在阻塞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;
}
}
中断是对线程的一个指示,它应该停止正在做的事情并做其他事情。由程序员决定线程如何响应中断,但是线程终止是很常见的。 一个很好的参考:https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.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
推荐文章
- 一对多、多对一、多对多的区别?
- 从枚举中选择一个随机值?
- 如何从URL获取参数与JSP
- 如何在Eclipse中生成Javadoc注释?
- 找到java类从哪里加载
- 从集合中随机选取一个元素
- 为什么x == (x = y)和(x = y) == x不一样?
- 什么Java 8流。收集等价物可在标准Kotlin库?
- 等待未来的名单
- 如何检查JSON键是否存在?
- 为什么MongoDB Java驱动在条件中使用随机数生成器?
- 即使从未抛出异常,使用try-catch块的代价是否昂贵?
- 什么时候我们应该使用观察者和可观察对象?
- Java中的split()方法对点(.)不起作用。
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?