为什么我的睡眠线程没有被打断?

时间:2018-01-02 07:54:19

标签: java multithreading

我想打断一个睡眠线程,但它会抛出InterruptedException并且不会停止。当我将Thread.interrupt()放入catch块时,它会中断线程,但不是第一次尝试。

我有一条消息,当线程被中断时必须写入文件,但是它写了大约4-5次这个消息。所以我理解线程不会立即中断。为什么会这样,我该怎么做?

我的代码具有在运行时更改的可变线程数。每个线程调用方法printAndDelay,它使记录存档和休眠。但是我必须有机会在任何时刻从主线程中停止任何线程并将停止原因记录到同一个文件中。

void printAndDelay(String message, int delay)
{
    try {
        writeToLogFile(message, logFileName);
        Thread.sleep(delay);
    }
    catch (InterruptedException e)
    {
        writeToLogFile("The reason of cancelling", logFileName);
        Thread.currentThread().interrupt();
    }
}

我尝试通过此代码中断线程:

void stopOrder(String threadName)
{
    Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces();

    threads.keySet().stream()
        .filter(k -> k.getName().equalsIgnoreCase(threadName))
        .findFirst()
        .get()
        .interrupt();
}

我发现我可以找到这个帖子,但它会抛出InterruptException但不会停止线程。所以我试着通过将Thread.interrupt()放入catch块来阻止它。

2 个答案:

答案 0 :(得分:1)

对于要打印4-5次的消息,您可能会有一些循环多次调用printAndDelay

for (Object obj : someList)
{
    printAndDelay("hello", 1000);
}

不是在printAndDelay中处理异常,而是将其声明为抛出方法签名并从调用方法的位置处理它。

void printAndDelay(String message, int delay) throws InterruptedException
{
    writeToLogFile(message, logFileName);
    Thread.sleep(delay);
}

你会改变你的循环:

try
{
    for (Object obj : someList)
    {
        printAndDelay("hello", 1000);
    }
}
catch (final InterruptedException e)
{
    writeToLogFile("The reason of cancelling", logFileName);
}

如果"the reason of cancelling"不是常量,您可能希望将InterruptedException包装在其他异常类型中,可能是自定义类型,以向上传递消息。

答案 1 :(得分:0)

你需要这样做。通过抛出InterruptedException来停止执行该线程。

void printAndDelay(String message, int delay)  throws InterruptedException {

try {
    writeToLogFile(message, logFileName);
    Thread.sleep(delay);


} catch (InterruptedException e) {


    writeToLogFile("The reason of cancelling", logFileName);
    // propagate the exception
    throw e;
}

}

在run方法中,您需要恢复中断状态。

public void run() { 
    try {
         // whatever you want to do
         printAndDelay(.....
     }
     catch (InterruptedException e) { 
         // Restore the interrupted status
          Thread.currentThread().interrupt();
     }
}

我抛出InterruptedException并且不将它包装在另一个异常中的原因是我想在run方法中恢复线程的中断。您甚至可以在方法中恢复中断,然后抛出一些自定义异常或RuntimeException并停止执行您的线程。