class Thread3_1 extends Thread {
public static int count = 0;
String tname1;
public Thread3_1(String threadname) {
tname1 = threadname;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname1 + " : " + i);
count++;
if (count == 2) {
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
}
}
class Thread3_2 extends Thread {
String tname2;
public Thread3_2(String threadname) {
tname2 = threadname;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2 + " : " + i);
if (i == 5) {
Thread.currentThread().interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
在给予interrupt()
答案 0 :(得分:3)
中断线程只会为此线程设置一个中断标志true
。
线程本身有责任重新检查此标志的值,并在它为真时立即停止执行ASAP(通过从run()
方法返回)。
当线程处于休眠状态时(或者在wait()
,await()
之类的bocking调用中被阻塞时)设置了中断标志时,阻塞方法会抛出InterruptedException。线程也负责解决此异常并停止执行ASAP。
您的第一个线程会定期检查该标志并在其为真时退出,但在捕获InterruptedException时无法执行此操作。
你的第二个线程会自行中断,但是当它执行时它不会从run()
方法返回。
答案 1 :(得分:1)
您中断Thread3_2而不是Thread3_1。
在Thread3_2的run方法中,您正在调用
Thread.currentThread().interrupt();
这将向当前正在执行的线程发送一个中断,这是一个Thread3_2的实例。如果要中断Thread3_1,则需要对该线程的引用。
例如:
class Thread3_2 extends Thread{
Thread threadToInterrupt;
public Thread3_2(Thread threadToInterrupt) {
this.threadToInterrupt = threadToInterrupt;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2+ " : " +i);
if(i == 5){
threadToInterrupt.interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
答案 2 :(得分:0)
您正在中断的线程必须设计为通过从run()方法正常退出来处理中断请求。这意味着确保InterruptedExceptions导致代码突破循环。它还意味着在循环内定期检查中断的标志。还有其他一些难以处理的方案,例如不可中断的IO操作。
目标线程将自身重新标记为已中断也是一种很好的做法,因此调用堆栈中的调用者也可以获得中断的指示(在catch语句中使用Thread.currentThread()。interrupt() )。
答案 3 :(得分:0)
如上所述,您需要中断Thread3_1而不是Thread3_2。 应用此修复程序后,您仍然会遇到一个问题:
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
因此,如果在睡眠中断发生时,中断标志将被清除并且isInterrupted()方法将返回false,因此将不满足以下条件:
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
所以你需要在catch块中处理它,即如果在catch(被中断)中返回
答案 4 :(得分:0)
来自Java教程:
许多抛出InterruptedException的方法,例如sleep,都是 旨在取消当前的操作并立即返回 收到一个中断。
如果一个线程长时间没有调用一个方法怎么办? 抛出InterruptedException?然后它必须定期调用 Thread.interrupted,如果有中断,则返回true 接收。*
*换句话说:其他不抛出InterruptedException的方法必须定期调用 Thread.interrupted,如果有中断,则返回true 接收。
在此解释:http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html