我有一个调用work()方法的线程,这是一个简单的while(true)-loop,如下所示;
public void work() throws InterruptedException {
while (true) {
// PART A
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART A::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
// Is it possible to make the below code executable at runtime when thread is interrupted?
// PART B
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART B::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
}
}
我运行这个线程实例并在一段时间后使用Thread.sleep()方法从main中断线程。当我更改延迟时,我希望在主线程中断线程时点击注释部分,但我只看到下面的输出;
....run()::Work::starting
.main()::interrupting thread t
.main()::leaving
....run()::work::PART A::isInterrupted():true
....run()::Work::ERROR::INTERRUPTED
我的简单问题是,是否可以执行work()方法的第二部分(B部分),如果没有,为什么?
完整的演示如下;
public class GeneralInterrupt implements Runnable {
public void run() {
try {
System.out.println("....run()::Work::starting");
work();
System.out.println("....run()::Work::ended");
} catch (InterruptedException x) {
System.out.println("....run()::Work::ERROR::INTERRUPTED");
return;
}
System.out.println("....run()::Work::leaving normally");
}
public void work() throws InterruptedException {
while (true) {
// PART A
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART A::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
// Is it possible to make the below code executable at runtime when thread is interrupted?
// PART B
if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART B::isInterrupted():" + Thread.currentThread().isInterrupted());
Thread.sleep(2000);
}
}
}
public static void main(String[] args) {
Thread t = new Thread(new GeneralInterrupt());
t.start();
try {
Thread.sleep(3000);
} catch (InterruptedException x) {
}
System.out.println(".main()::interrupting thread t");
t.interrupt();
System.out.println(".main()::leaving");
}
}
另请注意,如果从A和B部分删除“Thread.sleep(2000)”行,则输出为
....run()::work::PART B::isInterrupted():false
....run()::work::PART B::isInterrupted():false
....run()::work::PART B::isInterrupted():false
....run()::work::PART B::isInterrupted():false
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
....run()::work::PART A::isInterrupted():true
任何人都可以解释为什么Thread.sleep()方法在work()方法中以这种方式运行。
答案 0 :(得分:0)
当您中断线程并且它在sleep
方法中时,sleep
将抛出InterruptedException
。您不处理此异常。它会传播到您的run
方法,并且您的while
循环会退出。
您需要使用try / catch包围sleep
并抓住InterruptedException
。如果希望Thread.currentThread().interrupt()
在异常后返回true,则还必须确保在捕获isInterrupted()
后调用 if (Thread.currentThread().isInterrupted()) {
System.out.println("....run()::work::PART A::isInterrupted():"
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
,因为异常将重置中断标志。像这样:
Thread
答案 1 :(得分:0)
根据Oracle Tutorial,中断线程是线程发出信号以结束其当前工作并执行其他操作(如终止)的信号:
中断是一个线程的指示,它应该停止它正在做的事情并做其他事情。由程序员决定线程如何响应中断,但线程终止是很常见的。这是本课中强调的用法。
因此,通常应该可以在中断后继续。
根据中断的JavaDoc,它取决于线程被中断的位置:
如果在调用Object类的wait(),wait(long)或wait(long,int)方法,或者join(),join(long),join(long)时阻塞了这个线程,int), sleep(long),或者sleep(long,int),这个类的方法,然后它的中断状态将被清除,它将收到一个 InterruptedException的。 (我强调)
这就是使用sleep(2000)
时出现异常的原因。
答案 2 :(得分:0)
Thread.isInterrupted()
doesn't clear the interrupted status of the thread。因此,当您致电sleep()
时,会抛出InterruptedException
。您需要致电Thread.interrupted()
而不是Thread.currentThread().isInterrupted()
。
然而,这意味着B部分仅在A部分睡眠期间发生中断时执行,这似乎是您想要的。如果在A部分运行时需要B部分运行,则将其放入同一个块而不是在第二次测试之后。