Java 如何将您的程序与对“a”的调用隔离开来;“坏的”;应用程序编程接口?

Java 如何将您的程序与对“a”的调用隔离开来;“坏的”;应用程序编程接口?,java,multithreading,multiprocessing,Java,Multithreading,Multiprocessing,当我使用Java开发一个(学术)软件时,我被迫使用一个API,该API的实现相当糟糕。这意味着对特定输入数据集的API调用有时将永远不会返回。这一定是软件中的一个缺陷,因为它提供的算法是确定性的,有时它会在一组数据上终止,有时它会在同一组数据上运行到无限循环中 然而,修复API或重新实现它完全超出了范围。我甚至有源代码,但API严重依赖其他API,这些API没有文档记录,也没有源代码,并且在web上消失了(或者从未出现过?)。另一方面,这个“糟糕”的API是唯一一个解决了我遇到的特定问题的API

当我使用Java开发一个(学术)软件时,我被迫使用一个API,该API的实现相当糟糕。这意味着对特定输入数据集的API调用有时将永远不会返回。这一定是软件中的一个缺陷,因为它提供的算法是确定性的,有时它会在一组数据上终止,有时它会在同一组数据上运行到无限循环中

然而,修复API或重新实现它完全超出了范围。我甚至有源代码,但API严重依赖其他API,这些API没有文档记录,也没有源代码,并且在web上消失了(或者从未出现过?)。另一方面,这个“糟糕”的API是唯一一个解决了我遇到的特定问题的API,所以我必须坚持使用它

问题是:处理行为恶劣的API的最干净的方法是什么?当我遇到这个问题时,我决定将对API的调用放在一个单独的线程中。然后,另一个线程会偶尔检查该线程是否已终止。如果经过了一定的时间,我会使用
thread\stop()
终止处理线程,然后再次开始处理,希望下次它会返回。现在,我知道(当时也知道)此方法已被弃用,不能使用。但在这种学术背景下,让软件可能运行到未定义的状态而不是崩溃是可以接受的

仅仅忽略运行在无限循环中的处理线程也是不可接受的,因为它执行了一些CPU密集型操作,这会显著降低用户机器的速度


我没有尝试的另一种方法是在单独的进程而不是线程中启动处理,因为子进程可以干净地终止,而不会使软件处于不一致的状态。或者新的
SwingWorker
类(尚未提供)可以完成这项工作吗?它有一个
cancel()
方法,但文档中说它“试图取消此任务的执行”,因此它看起来也不是一个可靠的方法。

我建议使用单独的过程。在Java中,一个线程杀死第二个线程基本上没有安全的方法,除非第二个线程定期检查它是否被中断

理想的解决方案是使用分离物。隔离本质上是一个私有虚拟机,Java应用程序可以创建、管理和与之通信。特别是,父应用程序可以安全地杀死隔离及其所有线程

参考:


问题是要找到一个支持隔离的JVM。

我非常喜欢这类事情的独立进程

生成子进程并等待结果

如果API是不确定的,则将计时器线程放入包装器中,使坏API进入主程序


这样,子流程总是在给定的时间内结束。它要么产生一个有用的结果,要么产生一个表明失败的系统退出代码。

最好的办法就是重新实现有问题的API。然而,正如您所说,这是一个非常沉重的负担,可能超出了解决方案的范围

如果可能的话,下一个最好的方法是包装API。基本上,如果您可以提前确定导致故障的数据集是什么,您可以拒绝保证确定性的调用。这听起来也不适用于您,因为您认为,使用同一数据集重复调用有时会在之前的调用中无限循环时终止

鉴于上述选项不可用:

我认为您当前的线程解决方案是错误选择中最好的。从性能的角度来看,为方法调用旋转一个进程似乎太重了,这是不可接受的,即使它比使用线程更安全。这是非常危险的,但是如果你虔诚地防止任何锁定,你可以逃脱。

@S.Lott和@Stephen C的答案都是关于如何处理这种情况的正确答案,但是我想补充一点,在非学术环境中,你也应该寻求尽快更换API。在我们被一个糟糕的API锁定的情况下,通常是由于其他原因选择了一个出售的解决方案,随着时间的推移,我一直在努力用我自己的功能替换这个功能。你的客户不会像你的教授那样宽容,因为他们实际上必须使用你的软件(或者不使用!),而不仅仅是给它评分


当然,在某些情况下,使用管道胶带是解决问题的适当选择。但是,当它导致您描述的不良行为时,最好不要依赖它太久,开始真正的修复工作。

我不太同意您的观点。一次最多只能有一个子流程。在这个子进程中,真正的CPU密集型计算将发生,所以我不明白为什么创建另一个进程是如此重要。我想您假设将有许多子进程,但我的程序总是只需要一个子进程。不过,在它之间传递和检索数据会有一些开销,但这也不难做到。无论如何,谢谢你的回答。我关心的是启动一个进程的成本,而不是任何时候的进程数量或活动。进程成本>>线程的启动时间成本。我有点假设您正在重复调用这个API,考虑到所写的问题,我觉得这是公平的(尽管您的实际情况可能并非如此)。API的CPU密集程度与此无关,因为不管修复如何,您都要为此付出代价。我接受您的答案是因为对隔离API的有趣引用。谢谢你!谢谢