Java - 如何中断繁忙的线程

时间:2011-11-10 18:43:56

标签: java multithreading aes

我正在尝试中断在文件上运行AES加密的线程。这可能需要一段时间,到目前为止我已经提出了这个问题。

此正文位于按钮激活事件中。当用户再次单击该按钮时(else子句)。线程应该被中断,但如果我能完全停止线程,我会更高兴。但这已被弃用。

无论如何,线程忽略.interrupt()并继续执行aes256File。它确实引发了fileEncryptThread.isInterrupted()标志,但是从cpu使用情况我可以看到它仍然继续处理文件。

我已阅读有关安全停止线程的指南,但我不想完全重新设计我已经很慢的AES实现来检查类外中断标志......

    fileEncryptThread = new FileThread() // new thread please
    {
        @Override
        public void run()
        {
            String result = "";
            result = MyCrypto.aes256File(enInPath,
                                         enOutPath, 
                                         charsToString(passT.getPassword()),
                                         sec);
            if (!"".equals(result)) // error handling
            {
                JOptionPane.showMessageDialog(null,result);
            }
        }
    };
    fileEncryptThread.start();
  }
  else // if stop clicked
  {
      fileEncryptThread.interrupt();

3 个答案:

答案 0 :(得分:4)

为了有效地中断线程,必须以可中断的方式写入该线程。也就是说,检查

  

Thread.currentThread()。isInterrupted()

布尔并在其上行动。

在您的应用中,您应该验证

  

result = MyCrypto.aes256File(enInPath,                                           enOutPath,                                           charsToString(passT.getPassword()),                                           秒);

以这种方式行事(如果它是第三方库,则应该是javadoc)。如果它不可中断,你可以选择另一种加密实现。

答案 1 :(得分:2)

AFAIK,线程终止的唯一安全方法是从线程的“main”方法返回(通常在Runnable或Thread中运行run())。例如,您可以在MyCrypto.aes256File -method中使用while(<some class member boolean>) -loop并将布尔值设置为false,这样线程就会脱离循环并退出返回一个值,表明该过程未完成。

答案 2 :(得分:1)

可能的另一种方法(我不太了解AES算法)会将文件从加密中分离出来。读线程将从文件中填充大容量缓冲区并将它们排队到加密线程。加密线程将处理缓冲区并将“已使用”的缓冲区队列回读取器线程。通过将I / O等待移出加密器,这既可以轻松停止两个线程,又可以提高性能,尤其是在多核机器上。加密线程可能永远不必等待磁盘读取 - 如果加密线程有足够的缓冲区进入队列,则读取器线程暂时等待磁盘头移动无关紧要(即使在单核上机)。如果读取器线程超前于加密器,则固定数量的缓冲区和两个(阻塞,线程安全)队列提供流控制。

然后实际的停止机制变得有些微不足道。避免磁盘延迟的好处将会浪费偶尔检查标志的浪费时间,例如。就在前往下一个缓冲区的队列之前。

然后,排队缓冲区还允许向缓冲​​区添加序列号,从而允许所有内核处理加密。