Rhino Script Engine 的生命周期和并发语义是什么
我对(Rhino)脚本引擎和相关类的生命周期和并发语义感兴趣。具体来说:
Bindings
应该是线程安全的吗?- 是否应该允许多个线程共享单个 ScriptEngine 实例?
- ...或者每个线程应该构造一个短暂的实例?
- ...或者把它们放在池子里?
- 如果多个线程同时调用 ScriptEngine.eval(...) 会发生什么?
- 对于
CompiledScript
实例有同样的问题, - 对于使用
Invocable.getInterface(...)
生成的接口实现也有同样的问题吗? - 据推测,放置在 Bindings 中的对象遵循 Java 的垃圾回收。对于未在绑定中结束的对象进行垃圾回收怎么样?
I am interested in the lifecycle and concurrency semantics of (Rhino) Script Engine and associated classes. Specifically:
- Is
Bindings
supposed to be thread safe? - Should multiple threads be allowed to share a single ScriptEngine instance?
- ... or should each thread construct a short-lived instance?
- ... or keep them in a pool?
- What happens if multiple threads concurrently call
ScriptEngine.eval(...)
? - Same questions for
CompiledScript
instances - Same questions for interface implementations generated using
Invocable.getInterface(...)
? - 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以我运行了实验,Rhino 引擎报告“Mozilla Rhino”是多线程的,JavaDocs 断言了这一点
这是代码...对我来说它看起来是线程安全的,只要您传入的绑定也是线程安全的。...
输出是...
要回答您的具体问题...
绑定应该是线程安全的吗?
在我看来,你有责任使它们成为线程安全的。换句话说,只传入不可变对象,引擎是否线程安全就不再是问题了。
是否应该允许多个线程共享单个 ScriptEngine 实例?
在我看来,他们可以,但关键是可以通过绑定进行状态共享。不可变对象是你的朋友。
...或者每个线程都应该构造一个短暂的实例吗?
在我看来,最好的思考方式是 eval 的每次执行都是一个短暂的实例。
...或者把它们放在池子里?
在当今时代,尝试独自集中资源几乎不是一个好主意。尝试一下短暂的实例,测量其性能,然后从那里开始工作。
如果多个线程同时调用 ScriptEngine.eval(...) 会发生什么?
如果我正确理解了 Rhino 引擎对多线程的响应,ScriptEngine.eval 应该可以很好地处理并发调用。
CompiledScript 实例有同样的问题
JavaDocs 声明“在引擎后续执行脚本期间,由执行 CompiledScript 引起的 ScriptEngine 状态变化可能是可见的”。 http://docs.oracle.com/javase/6 /docs/api/javax/script/CompiledScript.html。因此,在您似乎试图最小化 ScriptEngine 实例数量的环境中,它们听起来根本不是线程安全的。
对于使用 Invocable.getInterface(...) 生成的接口实现有同样的问题吗?
你在这里只能靠你自己了。我不明白为什么或何时使用此功能,在我看来,您可能在这里“跳鲨鱼”。如果您想深入了解脚本语言,我建议您放弃 JavaScript,转而使用 Groovy 来获得更具脚本性的 Java。
大概,放置在 Bindings 中的对象遵循 Java 的垃圾回收。对于未在绑定中结束的对象进行垃圾回收怎么样?
如果它们最终没有绑定,我希望它们绑定到 ScriptEngine 并遵循其生命周期(基于我读过的文档)。池化 ScriptEngine 实例听起来并不是一个好主意。
So I've run the experiment and the Rhino engine reports "Mozilla Rhino" is MULTITHREADED which the JavaDocs asserts
Here's the code...it looks threadsafe to me, as long as the bindings you pass in are threadsafe too.
...the output is...
To answer your exact question...
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.
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.
...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.
... 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.
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.
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.
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.
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.