我正在尝试中断正在文件上运行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等待移出加密器来提高性能,特别是在多核机器上。加密线程可能永远不需要等待磁盘读取——如果加密线程在队列中有足够的缓冲区(即使在单核机器上),读取线程对磁盘磁头移动的临时等待并不重要。固定数量的缓冲区和两个(阻塞的,线程安全的)队列提供了流控制,如果读取线程领先于加密器。
实际的停止机制就变得微不足道了。避免磁盘延迟的好处将超过偶尔检查标志所浪费的时间。在进入下一个缓冲区的队列之前。
排队缓冲区还允许向缓冲区添加序列号,从而允许所有核心都可以进行加密。