Rhino Script Engine 的生命周期和并发语义是什么

发布于 2024-11-28 07:55:55 字数 435 浏览 0 评论 0原文

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

  1. Bindings 应该是线程安全的吗?
  2. 是否应该允许多个线程共享单个 ScriptEngine 实例?
  3. ...或者每个线程应该构造一个短暂的实例?
  4. ...或者把它们放在池子里?
  5. 如果多个线程同时调用 ScriptEngine.eval(...) 会发生什么?
  6. 对于 CompiledScript 实例有同样的问题,
  7. 对于使用 Invocable.getInterface(...) 生成的接口实现也有同样的问题吗?
  8. 据推测,放置在 Bindings 中的对象遵循 Java 的垃圾回收。对于未在绑定中结束的对象进行垃圾回收怎么样?

I am interested in the lifecycle and concurrency semantics of (Rhino) Script Engine and associated classes. Specifically:

  1. Is Bindings supposed to be thread safe?
  2. Should multiple threads be allowed to share a single ScriptEngine instance?
  3. ... or should each thread construct a short-lived instance?
  4. ... or keep them in a pool?
  5. What happens if multiple threads concurrently call ScriptEngine.eval(...)?
  6. Same questions for CompiledScript instances
  7. Same questions for interface implementations generated using Invocable.getInterface(...)?
  8. Presumably, objects placed in Bindings follow Java's garbage collection. What about garbage collection of objects that don't end up in the bindings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放我走吧 2024-12-05 07:55:55

所以我运行了实验,Rhino 引擎报告“Mozilla Rhino”是多线程的,JavaDocs 断言了这一点

“MULTITHREADED” - 引擎实现内部是线程安全的
并且脚本可以同时执行,尽管脚本的效果
一个线程上的执行可能对其他线程上的脚本可见。”

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

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,线程:空
引擎名称:Mozilla Rhino,线程:多线程

要回答您的具体问题...

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

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

  3. ...或者每个线程都应该构造一个短暂的实例吗?
    在我看来,最好的思考方式是 eval 的每次执行都是一个短暂的实例。

  4. ...或者把它们放在池子里?
    在当今时代,尝试独自集中资源几乎不是一个好主意。尝试一下短暂的实例,测量其性能,然后从那里开始工作。

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

  6. CompiledScript 实例有同样的问题
    JavaDocs 声明“在引擎后续执行脚本期间,由执行 CompiledScript 引起的 ScriptEngine 状态变化可能是可见的”。 http://docs.oracle.com/javase/6 /docs/api/javax/script/CompiledScript.html。因此,在您似乎试图最小化 ScriptEngine 实例数量的环境中,它们听起来根本不是线程安全的。

  7. 对于使用 Invocable.getInterface(...) 生成的接口实现有同样的问题吗?
    你在这里只能靠你自己了。我不明白为什么或何时使用此功能,在我看来,您可能在这里“跳鲨鱼”。如果您想深入了解脚本语言,我建议您放弃 JavaScript,转而使用 Groovy 来获得更具脚本性的 Java。

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

So I've run the experiment and the Rhino engine reports "Mozilla Rhino" is MULTITHREADED which the JavaDocs asserts

"MULTITHREADED" - The engine implementation is internally thread-safe
and scripts may execute concurrently although effects of script
execution on one thread may be visible to scripts on other threads."

Here's the code...it looks threadsafe to me, as long as the bindings you pass in are threadsafe too.

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" ) ) );
        }
    }
}

...the output is...

engineName: AppleScriptEngine, THREADING: null
engineName: Mozilla Rhino, THREADING: MULTITHREADED

To answer your exact question...

  1. Is Bindings supposed to be thread safe?
    It sounds to me that it is your responsibility to make them Thread-safe. In other words, pass in only immutable objects and whether the engine is Thread-safe or not becomes a non-issue.

  2. Should multiple threads be allowed to share a single ScriptEngine instance?
    It sounds to me like they can, but the key is the state sharing that can occur through the Bindings. Immutable objects are your friend.

  3. ...or should each thread construct a short-lived instance?
    It seems to me that the best way to think of this is that each execution of eval is a short lived instance.

  4. ... or keep them in a pool?
    In this day and age attempting to pool resources on your own is rarely a good idea. Give the short-lived instance a shot, measure its performance, and work out from there.

  5. What happens if multiple threads concurrently call ScriptEngine.eval(...)?
    If I understand the Rhino engine's repsonse to MULTITHREADING correctly, ScriptEngine.eval should be fine with concurrent calls.

  6. Same question for CompiledScript instances
    The JavaDocs state that "Changes in the state of the ScriptEngine caused by execution of the CompiledScript may visible during subsequent executions of scripts by the engine." http://docs.oracle.com/javase/6/docs/api/javax/script/CompiledScript.html. So they don't sound Thread-safe at all in an environment where you appear to be trying to minimize the number of ScriptEngine instances.

  7. Same questions for interface implementations generated using Invocable.getInterface(...)?
    You are on your own here. I don't understand exactly why or when this capability would be used and it sounds to me like you may be "jumping the shark" here. If you want to go this deep into the scripting language, I recommend that you abandon JavaScript and look at Groovy for a more scriptable Java.

  8. Presumably, objects placed in Bindings follow Java's garbage collection. What about garbage collection of objects that don't end up in the bindings?
    If they don't end up in bindings I expect them to be bound to the ScriptEngine and follow its lifecycle (based upon the docs that I have read). Pooling the ScriptEngine instances does not sound like a great idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文