如何销毁一个Java ScriptEngine实例?

5

我正在使用Java 8。虽然我不是Java专家(10年前上大学时就没再接触过Java),但我创建了一个ScriptEngine实例(如果有影响,是Nashorn)。我用它来评估多个JavaScript文件。

这个脚本在自己的小型JavaScript世界中很顺利地运行。我很喜欢它。

我还运行了一个文件系统WatchService,以防一些Java脚本被修改。当它们被修改时,我会创建一个新的ScriptEngine,并使用新的ScriptEngine对象评估JavaScript文件的新版本。

我的问题是,一旦我创建了新的ScriptEngine,就无法“终止”旧的scriptEngine。旧的脚本将无限期地运行。

我真的想释放旧的scriptEngine对象使用的资源。而且我希望它停止执行它正在做的事情(因为如果两个实例都尝试执行相同的任务,则可能会发生冲突)。

那么...如何完全消除旧的ScriptEngine,包括其中生成的任何线程?


考虑使用并发工具而不是原始线程。 - McDowell
1
你有找到解决方法吗?对我来说,这似乎是脚本引擎API中的一个漏洞。 - T.J. Crowder
2
@T.J.Crowder,基于这个严重的缺陷,我完全放弃了这个项目。 - Brent Larsen
@BrentLarsen:哇,疼。谢谢告诉我。 - T.J. Crowder
1个回答

0

好的,旧问题是线程泄漏。你有线程的句柄吗?有东西继承了Thread吗?那么可以这样:

private void stopThread(Thread thread) {
    final Thread moribund = thread;
    if (moribund != null) {
        thread = null;
        moribund.interrupt();
    }
}

或许这会有所帮助。


线程是在JavaScript文件中使用类似以下代码创建的:(new Thread(function() {...})).start(); 如果需要,我可以创建一个包含所有已生成线程的大型数组。 - Brent Larsen
我更倾向于在我的应用程序的Java端解决它们(而不是在应用程序的JS部分内部)。因为我对Java端有控制权。我真的希望能找到一种方法,只需关闭脚本引擎,这样它就会释放与之相关的所有资源。我不想依赖脚本构建者自己清理工作来确保我的应用程序稳定。 - Brent Larsen
你能将线程添加到线程组中吗?这是在线程构造函数内完成的。然后,您可以一次性终止所有线程。 - atmin
使用脚本引擎的目的是允许其他人在脚本中“做任何他们想做的事情”,而不会破坏Java应用程序。我无法控制他们在其中决定做什么。我可以(可能)创建一个漂亮的ThreadSpawner类,并要求他们使用它,否则如果他们的东西出了问题就得不到任何帮助。但实际上这不仅仅涉及线程,当ScriptEngine过期时,我希望与之相关的所有内容都被清理,并且所有内存和其他资源都可供其他事物使用。 - Brent Larsen
好的,我进行了一些调查,但没有取得很大的成功。最后的方法可能是使用JavaScript的“clearInterval”(如果在Nashorn中可以实现的话)。但是再次提醒,这里应该有一个信号。抱歉,我想我无法帮到你了。祝你好运。 - atmin
即使没有线程,似乎也没有办法销毁引擎。如果用户运行 while true { print "LOL" },似乎没有办法销毁引擎并停止执行? - Josh Wulf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接