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

Java Rhino脚本引擎的生命周期和并发语义是什么,java,concurrency,rhino,lifecycle,Java,Concurrency,Rhino,Lifecycle,我对(Rhino)脚本引擎和相关类的生命周期和并发语义感兴趣。具体而言: 绑定是否应该是线程安全的 是否应该允许多个线程共享一个ScriptEngine实例 。。。或者每个线程都应该构造一个短期实例 。。。还是把它们放在游泳池里 如果多个线程同时调用ScriptEngine.eval(…),会发生什么情况 CompiledScript实例的问题相同 使用Invocable.getInterface(…)生成的接口实现也有同样的问题吗 据推测,放置在绑定中的对象遵循Java的垃圾收集。对不在绑定中

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

  • 绑定是否应该是线程安全的
  • 是否应该允许多个线程共享一个ScriptEngine实例
  • 。。。或者每个线程都应该构造一个短期实例
  • 。。。还是把它们放在游泳池里
  • 如果多个线程同时调用
    ScriptEngine.eval(…)
    ,会发生什么情况
  • CompiledScript
    实例的问题相同
  • 使用Invocable.getInterface(…)生成的接口实现也有同样的问题吗
  • 据推测,放置在绑定中的对象遵循Java的垃圾收集。对不在绑定中的对象进行垃圾收集怎么样

  • 所以我运行了这个实验,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" ) ) );
            }
        }
    }
    
    package org.rekdev;
    导入java.util.*;
    导入javax.script.*;
    公共类JavaScriptWTF{
    公共静态void main(字符串[]args){
    ScriptEngineManager mgr=新建ScriptEngineManager();
    List factories=mgr.getEngineFactories();
    用于(ScriptEngineFactory工厂:工厂){
    System.out.println(String.format(
    “引擎名:%s,线程:%s”,
    factory.getEngineName(),
    getParameter(“线程”));
    }
    }
    }
    
    …输出是

    engineName:AppleScriptingine,线程:null
    engineName:Mozilla Rhino,线程:多线程

    要回答您的确切问题…

  • 绑定应该是线程安全的吗?
    在我看来,让它们线程安全是你的责任。换句话说,只传递不可变的对象,引擎是否线程安全就不是问题了

  • 是否应允许多个线程共享单个ScriptEngine实例?
    我觉得他们可以,但关键是可以通过绑定实现状态共享。不可变对象是你的朋友

  • …还是每个线程都应该构造一个短期实例?
    在我看来,考虑这一点的最佳方式是eval的每次执行都是一个短暂的实例

  • …还是把它们放在游泳池里?
    在当今这个时代,尝试自己集中资源很少是一个好主意。尝试一下这个短命的实例,衡量它的性能,然后从中着手

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

  • 对于CompiledScript实例,同样的问题
    JavaDocs声明“由执行编译脚本引起的脚本引擎状态的更改可能在引擎后续执行脚本时可见。”。因此,在您似乎试图最小化脚本引擎实例数量的环境中,这些更改听起来根本不是线程安全的

  • 对于使用Invocable.getInterface(…)生成的接口实现,是否存在相同的问题? 你在这里只能靠你自己。我不明白为什么或者什么时候会使用这个功能,我觉得你可能在这里“跳槽”。如果你想深入到脚本语言中,我建议你放弃JavaScript,去Groovy寻找一个更具脚本性的Java

  • 大概,放置在绑定中的对象遵循Java的垃圾收集。对不在绑定中的对象进行垃圾收集怎么样?
    如果它们最终没有绑定,我希望它们绑定到ScriptEngine并遵循其生命周期(基于我读过的文档)。将ScriptEngine实例合并听起来不是一个好主意


  • 我不知道,但JavaDocs建议您可以询问实现的线程安全保证:查看getParameter方法并使用线程。我希望得到关于池与实例化的更明确的答案,但您已经涵盖了大部分内容。感谢您的研究。