5

我正在使用Apache Commons Pool创建一个 Nashorn 引擎池。在应用程序启动时,我调用以将所有脚本的实例数preparePool()预热到引擎中,以便它准备好立即响应调用。minIdleeval()invokeFunction()

热身赛

@Override
public NashornScriptEngine create() {
    // ...
    try {
        engine.eval(asset1);
        engine.eval(asset2);
        engine.eval(asset3);
    } // ...
    return engine;
}

根据池大小和预加载脚本的复杂性,这需要相当长的时间。

问题

  • 我可以只预热一个实例并安全地将其克隆到minIdle实例数量吗?

  • 可以安全地序列化和持久化已创建实例的克隆吗?(这将允许维护一个引擎缓存,仅在其中一项资产更改时才需要失效)

相关资源(将在适当时更新此部分)

4

1 回答 1

3

Nashorn 的引擎实例既不可克隆也不可序列化。不过,我建议您使用单个引擎实例并使用它ScriptEngine.createBindings()来创建多个Bindings对象并将它们汇集起来。您显然需要通过调用ScriptEngine.eval(String|Reader, Bindings)方法来初始化每个绑定。(您也可以使用ScriptContext对象而不仅仅是Bindings;它们实际上是绑定和输出/错误流的元组。)

使用单个的好处ScriptEngine是代码共享。将同一个脚本评估为多个绑定仍然只会编译一次脚本(如果您使用Compilable接口),并且所有函数对象的代码将由相同的编译字节码表示。

于 2015-12-06T20:56:21.590 回答