如何中断一个繁忙的线程



我正在尝试中断正在文件上运行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();

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

Thread.currentThread () .isInterrupted ()

布尔值,并据此操作。

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

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

就是以这种方式工作的(如果它是第三方库,它应该是javadoc'ed)。如果它不可中断,您将选择另一种加密实现。

我知道,线程终止的唯一安全方法是从线程的"main"方法返回(通常是Runnable或thread中的run())。例如,您可以在MyCrypto中使用while(<some class member boolean>) -循环。aes256File -method,并将布尔值设置为false,这样线程将脱离循环并退出,返回一个指示进程未完成的值。

另一种可能的方法(我不太了解AES算法)是将文件读取从加密中分离出来。读线程将从文件中填充较大的缓冲区,并将它们排队给加密线程。加密线程将处理缓冲区,并将"使用"的缓冲区排队返回给读取线程。这样既可以很容易地停止两个线程,又可以通过将I/O等待移出加密器来提高性能,特别是在多核机器上。加密线程可能永远不需要等待磁盘读取——如果加密线程在队列中有足够的缓冲区(即使在单核机器上),读取线程对磁盘磁头移动的临时等待并不重要。固定数量的缓冲区和两个(阻塞的,线程安全的)队列提供了流控制,如果读取线程领先于加密器。

实际的停止机制就变得微不足道了。避免磁盘延迟的好处将超过偶尔检查标志所浪费的时间。在进入下一个缓冲区的队列之前。

排队缓冲区还允许向缓冲区添加序列号,从而允许所有核心都可以进行加密。

最新更新