java - 检查所有进度标志后,如何终止进入资源密集型方法的java线程?
问题描述
基本问题是在外部安全地终止线程。
事件调度线程 (EDT) 会产生一个新的工作线程 (workerThread)。这个workerThread必须完成一个任务。该任务在一个循环的多次迭代中完成。每次迭代都有两部分——读取数据(IO),计算数据(Digest)。EDT 可以随时通过 workerThread 代码中的布尔标志 (FLAG_CANCEL) 向 workerThread 发出取消信号。这是问题所在 - 检查标志的唯一时间是在 IO 和/或摘要之后。这提供了高达子迭代级别的即时取消。
我想要的是在IO 或Digest期间取消。重复检查 Thread.interrupted 和检查 FLAG_CANCEL 是一样的。那是行不通的。由于 IO 和 Digest 不会抛出任何 InterruptedExceptions(也不能对其进行修改),因此 workerThread.interrupt() 不起作用(循环中的任何内容都不会被中断)。
- 如何就地终止 IO 或 Digest?
- 我可以安全地使用 Thread.stop() 吗(像重新初始化 unsafe-monitor-exposed-objects 一样安全)?
这是 EDT 调用
private final Runnable runnable= new Runnable() {
@Override
public void run() {
try {
//hasher is a global instance in EDT of Hasher class
hasher.hash(file);
} catch (NoSuchAlgorithmException ex) {
//do something
} catch (IOException ex) {
//do something
}
catch (InterruptedException ex) {
//do something
}
}
};
Thread workerThread=new Thread(runnable);
workerThread.setDaemon(true);
workerThread.start();
这是Hasher类的方法
synchronized public String hash(File file) throws NoSuchAlgorithmException, FileNotFoundException, IOException
{
FLAG_CANCEL_HASHING = false;//global
byte[] buffer =new buffer[calculateBufferSize()];
MessageDigest md = MessageDigest.getInstance(algorithm);
FileInputStream fis = new FileInputStream(file);
int bytesRead;
float totalBytesRead = 0;
//start hashing
while ((bytesRead = fis.read(buffer)) != -1)//IO
{
//check before Digest
if (FLAG_CANCEL_HASHING)
{
fireCancellationEvent();
return null;
}
md.update(buffer, 0, bytesRead);//Digest
//check before IO
iif (FLAG_CANCEL_HASHING)
{
fireCancellationEvent();
return null;
}
totalBytesRead += bytesRead;
fireProgressEvent(totalBytesRead );
}
fis.close();
return toHexString(md.digest());
}
我可以调用 workerThread.stop() 然后在下一次调用 runnable 时安全地使用 hasher 吗?
寻求解决方案- 是否足够(确保在下一次从 EDT 调用 hasher 时不会出现任何问题)
在 EDT && 中做 workerThread.stop
重新初始化哈希,FLAG_CANCEL_HASHING &&
取消后忽略所有触发的事件,
明确关闭 fis(首先使其成为全球性的)
(基本上在 EDT 中创建一个新的哈希实例)
请记住,所有需要的是在资源密集型 IO 或摘要期间终止,以免影响对哈希器的任何连续调用的工作。例如,在通过停止终止线程之后,调用 rutime.getRuntime.gc 是否会清理暴露的对象并防止在下一次调用 hasher 时出现任何不良行为?
解决方案
推荐阅读
- sql - 是否有任何替代自我加入的方法
- angular - 我可以在 Angular CLI 应用程序中将自定义中间件添加到开发服务器吗?
- swift - UIColletionViewCell 内的 UITextField 成为FirstResponder
- reporting-services - SSRS - 根据部署到的文件夹设置默认参数和数据源
- c - Unix:recvfrom()
- visual-studio-code - Windows 上的 VS Code:如何编译 Node/Linux 项目?
- docker - docker主进程上的MPI
- ios - 在 Swift 中将数组传递给通用数据源
- css - 除了 CSS 缩放之外,有没有办法使用 c# 和 selenium 来缩小 chrome?
- powershell - Import-Clixml 将 PSObject 值读取为 #text 并且不包含真实数据