单个 Thread.interrupt() 中断不止一次
Single Thread.interrupt() interrupts more than once
我创建了 MyTask
,它在 run()
中有 3 件事要做。我尝试 interrupt()
持有 MyTask
实例的线程。不幸的是,一旦它被打断,它就会结束,并且只有字符串 First task
会打印在控制台上。
public class MyTask implements Runnable {
private volatile Thread thread;
@Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
如果我在 run()
中添加 Thread.sleep(10)
它开始 正常工作 并打印 First task
、Second task
和终于在控制台上 Third task
。
问题是:为什么 Thread.interrupts()
只有添加 sleep()
才能正常工作?
public class MyTask implements Runnable {
private volatile Thread thread;
@Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
查看 Thread.sleep(long)
上的 Javadoc
Throws: InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
因此,添加 sleep
以及捕获(和忽略)任何异常都会导致观察到的行为。
示例:
没有 sleep()
:
- 线程以
interrupted = false
开始,因此第一个循环 运行s
- 线程被中断,即现在
interrupted = true
- 第一个循环检查
interrupted
但不检查 运行(再次)
- 第二个循环检查
interrupted
而根本不检查 运行
- 第 3 次循环检查
interrupted
而根本不检查 运行
- 完成
随着sleep()
- 线程开始于
interrupted = false
循环 1:
- 检查条件并执行正文,因为
interrupted = false
- 线程被中断,即现在
interrupted = true
- while 条件被检查但是这次
interrupted = true
所以循环结束
sleep()
被调用,由于线程已被中断,因此抛出异常并再次 interrupted = false
- 异常被捕获(并被忽略),因此继续正常执行
循环 2 和循环 3 重复步骤 2
- 完成
引用自Interrupts:
When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
含义:将您的代码从 thread.isInterrupted()
更改为 Thread.interrupted()
,然后重试。
循环之间的 sleep()
也会通过立即抛出 InterruptedException
来清除该标志(因为当前线程 已被 中断)
我创建了 MyTask
,它在 run()
中有 3 件事要做。我尝试 interrupt()
持有 MyTask
实例的线程。不幸的是,一旦它被打断,它就会结束,并且只有字符串 First task
会打印在控制台上。
public class MyTask implements Runnable {
private volatile Thread thread;
@Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
如果我在 run()
中添加 Thread.sleep(10)
它开始 正常工作 并打印 First task
、Second task
和终于在控制台上 Third task
。
问题是:为什么 Thread.interrupts()
只有添加 sleep()
才能正常工作?
public class MyTask implements Runnable {
private volatile Thread thread;
@Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
查看 Thread.sleep(long)
Throws: InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
因此,添加 sleep
以及捕获(和忽略)任何异常都会导致观察到的行为。
示例:
没有 sleep()
:
- 线程以
interrupted = false
开始,因此第一个循环 运行s - 线程被中断,即现在
interrupted = true
- 第一个循环检查
interrupted
但不检查 运行(再次) - 第二个循环检查
interrupted
而根本不检查 运行 - 第 3 次循环检查
interrupted
而根本不检查 运行 - 完成
随着sleep()
- 线程开始于
interrupted = false
循环 1:
- 检查条件并执行正文,因为
interrupted = false
- 线程被中断,即现在
interrupted = true
- while 条件被检查但是这次
interrupted = true
所以循环结束 sleep()
被调用,由于线程已被中断,因此抛出异常并再次interrupted = false
- 异常被捕获(并被忽略),因此继续正常执行
- 检查条件并执行正文,因为
循环 2 和循环 3 重复步骤 2
- 完成
引用自Interrupts:
When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
含义:将您的代码从 thread.isInterrupted()
更改为 Thread.interrupted()
,然后重试。
循环之间的 sleep()
也会通过立即抛出 InterruptedException
来清除该标志(因为当前线程 已被 中断)