你能解释一下调用java.lang.Thread.interrupt()时做什么吗?
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(),后者更像是用突击步枪射击线程。
如果目标线程一直在等待(通过调用wait(),或其他一些本质上做同样事情的相关方法,如sleep()),它将被中断,这意味着它将停止等待它正在等待的东西,而是接收一个InterruptedException。
完全由线程本身(调用wait()的代码)决定在这种情况下做什么。它不会自动终止线程。
它有时与终止标志结合使用。当被中断时,线程可以检查这个标志,然后关闭自己。但这只是惯例。
什么是中断?
中断是一个指示 线程应该停止它是什么 做和做别的事情。由 由程序员来决定 线程如何响应中断, 但这对于线程来说是很常见的 终止。
它是如何实现的?
实现了中断机制 使用内部标志 中断状态。调用 interrupt设置这个标志。当 线程通过检查中断 调用静态方法 中断状态 清除。非静态的 线程。被使用的isInterrupted 一个线程来查询中断 另一种状态,并不会改变 中断状态标志。
引用自Thread.interrupt() API:
Interrupts this thread. First the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown. If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException. If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. If none of the previous conditions hold then this thread's interrupt status will be set.
看看下面的内容,你就能完全理解:
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;
}
}
公共无效中断()
中断这个线程。
除非当前线程正在中断自身(这总是允许的),否则调用该线程的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()将目标线程的中断状态/标志设置为true,当使用thread. interrupted()检查时,可以帮助停止无休止的线程。请参阅http://www.yegor256.com/2015/10/20/interrupted-exception.html
线程中断基于标志中断状态。 对于每个线程,中断状态的默认值设置为false。 每当在线程上调用interrupt()方法时,中断状态被设置为true。
如果中断状态= true (interrupt()已经在线程上调用), 这个特定的线程不能进入睡眠状态。如果在该线程上调用sleep,则抛出中断异常。再次抛出异常后,标志被设置为false。 如果线程已经处于睡眠状态,并且调用interrupt(),线程将跳出睡眠状态并抛出中断的Exception。
Thread.interrupt()方法设置内部的“中断状态”标志。通常该标志由Thread.interrupted()方法检查。
按照惯例,任何通过InterruptedException存在的方法都必须清除中断状态标志。
在以上回答的基础上,我想补充一两件事。
需要记住的一件事是,调用中断方法并不总是会导致InterruptedException。因此,实现代码应该定期检查中断状态并采取适当的操作。 thread. currentthread (). isinterrupted()也可以用来检查线程的中断状态。与Thread.interrupted()方法不同,它不清除中断状态。
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂
- Java:检查enum是否包含给定的字符串?
- 它的意思是:序列化类没有声明一个静态的最终serialVersionUID字段?