Rhino 脚本引擎的生命周期和并发语义是什么

2022-09-01 11:02:28

我对(Rhino)脚本引擎和相关类的生命周期和并发语义感兴趣。具体说来:

  1. 应该是线程安全的吗?Bindings
  2. 是否应该允许多个线程共享一个 ScriptEngine 实例?
  3. ...还是每个线程都应该构造一个短期实例?
  4. ...还是把它们放在游泳池里?
  5. 如果多个线程同时调用,会发生什么情况?ScriptEngine.eval(...)
  6. 实例的相同问题CompiledScript
  7. 对于使用 生成的接口实现,存在相同的问题?Invocable.getInterface(...)
  8. 据推测,放置在Bindings中的对象遵循Java的垃圾回收。对最终不在绑定中的对象进行垃圾回收怎么办?

答案 1

因此,我运行了实验,Rhino引擎报告“Mozilla Rhino”是多线程的,JavaDocs断言

“多线程” - 引擎实现在内部是线程安全的,脚本可以并发执行,尽管脚本执行对一个线程的影响可能对其他线程上的脚本可见。

下面是代码...对我来说,它看起来是线程安全的,只要你传入的绑定也是线程安全的。

package org.rekdev;
import java.util.*;
import javax.script.*;
public class JavaScriptWTF {
    public static void main( String[] args ) {
        ScriptEngineManager mgr = new ScriptEngineManager();
        List<ScriptEngineFactory> factories = mgr.getEngineFactories();
        for ( ScriptEngineFactory factory : factories ) {
            System.out.println( String.format(
                    "engineName: %s, THREADING: %s",
                    factory.getEngineName(),
                    factory.getParameter( "THREADING" ) ) );
        }
    }
}

...输出是...

引擎名称: AppleScriptEngine, THREADING: null
engineName: Mozilla Rhino, THREADING: MULTITHREADED

要回答您的确切问题...

  1. 绑定应该是线程安全的吗?
    在我看来,你有责任使它们成为线程安全的。换句话说,只传入不可变对象,引擎是否线程安全就不再是问题。

  2. 是否应该允许多个线程共享一个 ScriptEngine 实例?
    在我看来,他们似乎可以做到,但关键是通过绑定可以发生的状态共享。不可变对象是你的朋友。

  3. ...还是每个线程都应该构造一个短期实例?
    在我看来,思考这个问题的最好方法是,eval的每次执行都是一个短暂的实例。

  4. ...还是把它们放在游泳池里?
    在这个时代,试图自己汇集资源很少是一个好主意。给短期实例一个机会,测量其性能,然后从那里开始计算。

  5. 如果多个线程同时调用 ScriptEngine.eval(...) 会发生什么情况?
    如果我正确地理解了Rhino引擎对多线程的回复,ScriptEngine.eval应该可以处理并发调用。

  6. 对于CompiledScript实例
    ,JavaDocs指出“在引擎随后执行脚本时,由编译脚本的执行引起的脚本引擎状态的变化可能会可见。http://docs.oracle.com/javase/6/docs/api/javax/script/CompiledScript.html。因此,在您似乎试图最小化ScriptEngine实例数量的环境中,它们听起来根本不是线程安全的。

  7. 对于使用 Invocable.getInterface(...) 生成的接口实现,也存在同样的问题?你在这里独自一人。我不明白为什么或何时会使用这种能力,在我看来,你可能在这里“跳过鲨鱼”。如果你想深入研究脚本语言,我建议你放弃JavaScript,看看Groovy,寻找一个更具脚本化的Java。

  8. 据推测,放置在Bindings中的对象遵循Java的垃圾回收。对最终不在绑定中的对象进行垃圾回收怎么办?
    如果它们最终没有绑定,我希望它们绑定到ScriptEngine并遵循其生命周期(基于我阅读的文档)。池化 ScriptEngine 实例听起来不是一个好主意。


答案 2

推荐