代码之家  ›  专栏  ›  技术社区  ›  Robert Petermeier

如何将程序从对“坏”API的调用中隔离出来?

  •  11
  • Robert Petermeier  · 技术社区  · 17 年前

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

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

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

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

    我没有尝试的另一种方法是在单独的数据库中开始处理 过程 SwingWorker cancel() 方法,但文档说 因此,这看起来也不是一个可靠的方法。

    4 回复  |  直到 17 年前
        1
  •  11
  •   jan.supol    10 年前

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

    参考: JSR-000121 Application Isolation API Specification - Final Release

    问题在于找到一个支持隔离的JVM。

        2
  •  5
  •   S.Lott    17 年前

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

    生成子进程并等待结果。

        3
  •  2
  •   tvanfosson    17 年前

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

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

        4
  •  1
  •   Kevin Montrose    17 年前

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

    次佳 如果可能的话,事情将是包装API。基本上,如果您可以提前确定导致故障的数据集是什么,您可以

    鉴于上述选项不可用:
    我想你的 是 最坏的选择 . 从性能的角度来看,为方法调用旋转一个进程似乎太重了,这是不可接受的,即使它比使用线程更安全。 Thread.stop()