1

我有一个控制器和一个线程来做一些工作,控制器有一个中断功能,可以在紧急情况下关闭线程。

我的代码骨架看起来像这样:

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;
    }
}

但是,当调用中断时,永远不会捕获 InterruptedException。我在这里做错了什么?

4

6 回答 6

4

唯一想到的可能性:

  • 你没有打断线程(你确定th.interrupt()被调用了吗?)
  • 你打断另一个线程
  • 线程被中断,但 EmergencyProcedures 中存在一个问题,让您认为它没有被中断
  • 你永远不会启动线程,因此你不能中断它。
  • DoSomeWork()忽略中断
于 2012-10-15T12:22:39.533 回答
3

至少这是您的代码的问题:

th.sleep(1000); //make thread sleep first, still no effect

不,你不能让另一个线程休眠:你只会让当前线程休眠。您只是static sleep通过Thread.

调用th.interrupt()不会自动导致InterruptedException在另一个线程中被抛出。仅当线程的代码进入可中断方法(声明的方法InterruptedException)时才会发生这种情况。

您的主要误解(可能)与interrupt机制的性质有关。与不推荐使用的stop机制不同,interrupt它是协作的,因此是可选的:线程只接收中断信号并负责显式检查其状态。它可以以它认为合适的任何方式响应信号。

于 2012-10-15T12:29:42.733 回答
2

假设您正确调用th.interrupt();,则必须是在任何合理的时间内都没有“注意到”中断的情况。interrupt()调用线程时不会神奇地抛出中断。线程,一般来说,必须检测它何时被中断,并抛出自己的InterruptedException.

现在,这通常不是问题,因为Thread.sleep()还有一些其他常用方法旨在InterruptedException立即抛出。

您需要Thread.interrupted()不时手动检查一次,这将告诉您线程是否已被中断,这为您提供了类似的构造;

if (Thread.interrupted()) {
    throw new InterruptedException();
}

你会放在里面DoSomeWork();

DoSomeWork(); InterruptedException对了吗

于 2012-10-15T12:26:16.433 回答
1

就像@assylias 所说,或者您的线程不支持中断,请参阅支持中断部分:http ://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html 。基本上你需要使用支持中断的方法,比如 sleep 或 Thread.interrupted()。

于 2012-10-15T12:22:00.953 回答
0

你是在睡眠结束后打扰吗?根据文档

如果该线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法或 join()、join(long)、join(long, int) 时被阻塞, sleep(long), or sleep(long, int), 这个类的方法,那么它的中断状态会被清除并且会收到一个InterruptedException。

于 2012-10-15T12:30:26.043 回答
0

查看您创建的第一件事,Thread但您没有启动它。第二件事你不能InterruptedException在运行方法中捕获异常。请在开关状态 1 中尝试此操作。

           th = new Thread(new Runnable(){
            public void run(){
                try{
                    System.out.println("Run");
                    Thread.sleep(10000);
                    }
                catch(InterruptedException e)
                {
                    EmergencyProcedures();
                }
            }
            });
于 2012-10-15T12:32:39.393 回答