当我使用Java开发一款(学术)软件时,我被迫使用一个实施得很差的API。这意味着对某些输入数据集的此API调用有时永远不会返回。这一定是软件中的一个错误,因为它提供的算法是确定性的算法,有时它会终止于一组数据,有时会在同一组数据上陷入无限循环…
但是,修复API或重新实现它完全超出了范围。我什至拥有源代码,但该API严重依赖于其他未记录且没有源代码的API,这些API到那时已从网络消失(或从未出现过?)。另一方面,这个“不良” API是唯一解决我遇到的特定问题的API,因此我真的必须坚持下去。
问题是:处理表现得很讨厌的API的最干净方法是什么?遇到此问题时,我决定将对API的调用放在单独的线程中。然后,另一个线程偶尔会检查该线程是否已终止。如果经过了一定的时间,我将使用杀死处理线程Thread#stop(),然后再次开始处理,希望它在下一次返回。现在,我知道(并且在那时就知道了)此方法已被弃用,并且不能使用。但是在这种学术背景下,让软件 潜在地 运行到未定义状态而不是使其崩溃是可以接受的。
Thread#stop()
只忽略运行到无限循环中的处理线程也是不可接受的,因为它执行了一些占用大量CPU的操作,这将显着降低用户计算机的速度。
我没有尝试的另一种方法是在一个单独的 进程 而不是线程中启动处理,因为子进程可以干净地杀死,而无需将软件置于不一致的状态。还是新SwingWorker班级(尚未提供)可以完成这项工作?它有一个cancel()方法,但是文档说它 “试图取消执行此任务” ,因此它也不是可靠的方法。
SwingWorker
cancel()
我建议使用单独的过程。基本上,在Java中,没有一个线程可以杀死第二个线程的安全方法,除非定期检查第二个线程是否被中断。
理想的解决方案是使用隔离株。隔离实际上是Java应用程序可以创建,管理和通信的私有虚拟机。特别是,父应用程序可以安全地杀死隔离对象及其所有线程。
参考:JSR-000121应用程序隔离API规范- 最终版本
问题是找到支持隔离的JVM。