我有一个关于在Java中中断线程的问题。假设我有一个Runnable
:
public MyRunnable implements Runnable {
public void run() {
operationOne();
operationTwo();
operationThree();
}
}
我想实现这样的东西:
Thread t = new Thread(new MyRunnable());
t.run();
... // something happens
// we now want to stop Thread t
t.interrupt(); // MyRunnable receives an InterruptedException, right?
... // t is has now been terminated.
我如何在Java中实现这个?具体来说,我如何在MyRunnable
中捕获InterruptedException
?
我建议测试Thread.isInterrupted()
。Javadoc。这里的想法是,您正在做一些工作,很可能是在一个循环中。在每次迭代中,您都应该检查中断标志是否为真并停止工作。
while(doingWork && !Thread.isInterrupted() {
// do the work
}
Edit:要清楚,如果子任务没有阻塞或最坏的情况,则线程不会收到InterruptedException
。检查标志是正确的方法,但不是每个人都遵循它。
首先,第二块代码的第二行应该是t.start(),而不是t.run()。T.run()直接调用你的run方法。
是的,MyRunnable.run()必须在运行时定期检查Thread.currentThread(). isinterrupted()。由于您可能想在Runnable中做的许多事情都涉及到InterruptedExceptions,因此我的建议是咬紧牙关并接受它们。定期调用一个实用函数
public static void checkForInterrupt() throws InterruptedException {
if (Thread.currentThread().isInterrupted())
throw new InterruptedException();
}
编辑补充道
因为我看到一个评论,海报没有控制单独的操作,他的MyRunnable.run()代码应该看起来像
public void run() {
operation1();
checkForInterrupt();
operation2();
checkForInterrupt();
operation3();
}
只有当线程被阻塞(等待、睡眠等)时才会抛出InterruptedThreadException
。否则,您必须检查Thread.currentThread().isInterrupted()
。
我认为上面的答案非常适合你的问题。我只是想在InterruptedException
Javadoc说:
InterruptedException:当线程处于等待、睡眠或异常状态时抛出否则暂停很长时间,另一个线程会打断它在Thread类中使用中断方法。
这意味着在运行
时不会抛出InterruptedException
。operationOne();
operationTwo();
operationThree();
除非你正在睡觉,等待锁或者在这三个方法中的某个地方暂停。
EDIT如果提供的代码不能按照这里的漂亮和有用的答案所建议的那样更改,那么恐怕你没有办法打断你的线程。与c#等其他语言不同,在c#中,线程可以通过调用Thread.Abort()
来终止,而Java没有这种可能性。
首先,应该是class在那里
public class MyRunnable extends Thread {
public void run() {
if(!isInterrupted()){
operationOne();
operationTwo();
operationThree();
}
}
}
这样会更好吗?