【问题标题】:Do I have to use thread.interrupted()?我必须使用 thread.interrupted() 吗?
【发布时间】:2013-10-05 12:12:42
【问题描述】:

我正在为一个程序编写一个 GUI,该程序接受一些输入并在其上运行算法。该算法的代码相当长且复杂,因此我刚刚从 GUI 启动了一个新线程,以便对输入执行计算。

//algorithmThread previously initialized 
 if(e.getSource() == startButton) {
        if(update.updateStrings(textFields)) {
            algorithmThread.start();  
        }
    }

我们希望添加允许用户在提供错误输入文件的情况下停止计算(它在我的笔记本电脑上运行大约半小时然后产生结果)的功能。这就是我的处理方式。

 else if(e.getSource() == stopButton) {
        //if the user presses the stop button then intterupt the 
        //thread running the algorithm
        algorithmThread.interrupt();
        System.out.println("algorithm stopped"); //debugging code
        //recreate the thread in case the user hits the start button again
        algorithmThread = new Thread() {
                public void run() {
                    runNOC();
                }
            };
    }

程序确实成功地停止了算法(虽然我认为我应该做一些异常处理),允许用户输入新的输入,然后重新启动。我的问题是,在什么情况下我必须检查算法代码中的 Thread.interrupted() ?是否有必要/最佳实践?或者按上面说明的方式停止线程是否可以接受?

【问题讨论】:

  • this link 会帮助你
  • 你的方法很好。您检查中断标志的频率将直接与用户单击“停止”按钮后线程停止其工作所需的时间...

标签: java multithreading


【解决方案1】:

Thread.interrupt() 方法所做的只是设置一个“中断”标志,因此以这种方式停止线程需要它的合作。例如,算法应该每隔一段时间轮询一次中断状态,例如每次迭代一次。您可以在Java concurrency tutorial 中看到这样的示例。

由于您使用的是 GUI,您可能会发现使用 SwingWorker 运行后台线程更容易。这个类有很多方便 GUI 编程的特性,比如在计算完成时使用done 方法和canceling the computation 而不使用Thread.interrupt() 来更新 GUI。以这种方式取消仍然需要线程的配合,但更安全,因为中断线程会导致在某些情况下抛出InterruptedException,例如当线程在Thread.sleep 中休眠或在Object.wait 中等待锁定时.

【讨论】:

  • 只有当线程正在做一些可以被中断的事情时,它才会导致InterruptedException,例如休眠或等待。在正常执行状态下,仅设置标志。
  • @val Javadoc 到底说了什么?
  • 它准确地表明 Joni 帖子的第一次编辑是错误信息。
  • 好的。所以我想答案是肯定的,我必须检查执行计算的线程中的“中断”标志。我想这让我想到另一个问题。为什么在我调用 algorithmThread.interrupt() 后线程终止,尽管我没有在 algorithmThread 中检查 thread.interrupted() == true?
  • 严重:空 java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:996) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer. java:1303) 在 java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:248) 在 java.util.concurrent.FutureTask.get(FutureTask.java:111) 在 java.util.concurrent.AbstractExecutorService.invokeAll (AbstractExecutorService.java:243)
【解决方案2】:

interrupt 在这个帖子之后并不总是邪恶的: Is Thread.interrupt() evil?

在这里,我们在一个特定的地方使用这种方法:处理 中断异常。这可能看起来有点奇怪,但这就是 它看起来像在代码中:

try {
     // Some code that might throw an InterruptedException.  
     // Using sleep as an example
     Thread.sleep(10000); 
     } 
catch (InterruptedException ie) {
     System.err.println("Interrupted in our long run.  Stopping.");
     Thread.currentThread().interrupt(); 
     } 

这为我们做了两件事:

  1. 它避免吃掉中断异常。 IDE 自动异常处理程序 始终为您提供类似 ie.printStackTrace();和一个 活泼的“TODO:这里需要一些有用的东西!”评论。

  2. 它恢复 不强制检查异常的中断状态 方法。如果您正在实施的方法签名没有 throws InterruptedException 子句,这是您的另一个选择 传播中断状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 2012-04-28
    相关资源
    最近更新 更多