我有一个控制器和一个做一些工作的线程,控制器有一个中断功能,可以在紧急情况下关闭线程。
我的代码的骨架看起来像这样:
public class SomeController{
private Thread th;
public SomeController(){
th = null;
}
public void Input(int state){
switch(state){
case 0: //emergency shut off
if(th != null){
th.sleep(1000); //make thread sleep first, still no effect
th.interrupt();
}
break;
case 1: //thread creation
th = new Thread(new Runnable(){
public void run(){
try{
DoSomeWork();
}
catch(InterruptedException e)
{
EmergencyProcedures();
}
}
});
th.start();
break;
}
}
但是,当调用interrupt时,永远不会捕获InterruptedException。我在这里做错了什么?
答案 0 :(得分:4)
想到的唯一可能性:
th.interrupt()
吗?)DoSomeWork()
忽略了中断答案 1 :(得分:3)
至少这是您的代码的问题:
th.sleep(1000); //make thread sleep first, still no effect
不,你不能让另一个线程睡眠:你只能使当前线程休眠。您只是通过static sleep
。
Thread
方法
调用th.interrupt()
不会自动导致InterruptedException
在其他线程中抛出。只有当线程的代码进入可中断的方法(声明InterruptedException
的方法)时才会发生这种情况。
您的主要误解(可能)与interrupt
机制的性质有关。与弃用stop
机制不同,interrupt
合作,因此可选:线程只接收中断信号,有责任明确检查其状态。它可以以任何合适的方式响应信号。
答案 2 :(得分:2)
假设你正确地调用th.interrupt();
,必须是在任何合理的时间内没有“注意到”中断的情况。在线程上调用interrupt()
时,中断不会被神奇地抛出。一般来说,线程必须检测它何时被中断,并抛出自己的InterruptedException
。
现在,这通常不是问题,因为Thread.sleep()
和一些其他常用方法旨在立即抛出InterruptedException
。
您需要手动检查一次Thread.interrupted()
,这将告诉您线程是否已被中断,这为您提供了类似的结构;
if (Thread.interrupted()) {
throw new InterruptedException();
}
你要放在DoSomeWork();
内。
DoSomeWork();
确实抛出InterruptedException
吗?
答案 3 :(得分:1)
就像@assylias所说,或者您的主题不支持中断,请参阅:http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html中的支持中断部分。 基本上你需要使用支持中断的方法,比如sleep或Thread.interrupted()。
答案 4 :(得分:0)
睡眠结束后你打断了吗?根据{{3}}
如果在调用Object类的wait(),wait(long)或wait(long,int)方法,或者join(),join(long),join(long)时阻塞了这个线程,int),sleep(long)或sleep(long,int),这个类的方法,然后它的中断状态将被清除,它将收到InterruptedException。
答案 5 :(得分:0)
看到你创建的第一件事Thread
,但你没有启动它。第二件事你无法在run方法中捕获InterruptedException
异常。请在开关状态1中尝试此操作。
th = new Thread(new Runnable(){
public void run(){
try{
System.out.println("Run");
Thread.sleep(10000);
}
catch(InterruptedException e)
{
EmergencyProcedures();
}
}
});