I am interested in the lifecycle and concurrency semantics of (Rhino) Script Engine and associated classes. Specifically:
我对(Rhino)脚本引擎和相关类的生命周期和并发语义感兴趣。特别:
- 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?
绑定应该是线程安全的吗?
是否应该允许多个线程共享一个ScriptEngine实例?
...或者每个线程应该构建一个短期实例吗?
......还是把它们放在游泳池里?
如果多个线程同时调用ScriptEngine.eval(...)会发生什么?
CompiledScript实例的相同问题
使用Invocable.getInterface(...)生成的接口实现的问题相同?
据推测,放置在Bindings中的对象遵循Java的垃圾收集。那些没有在绑定中结束的对象的垃圾收集呢?
1 个解决方案
#1
23
So I've run the experiment and the Rhino engine reports "Mozilla Rhino" is MULTITHREADED which the JavaDocs asserts
所以我运行实验并且Rhino引擎报告“Mozilla Rhino”是多线程的,JavaDocs断言
"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."
“MULTITHREADED” - 引擎实现在内部是线程安全的,脚本可以并发执行,尽管脚本执行对一个线程的影响可能对其他线程上的脚本可见。“
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: MULTITHREADEDengineName:AppleScriptEngine,THREADING:null engineName:Mozilla Rhino,THREADING:MULTHTHREADED
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.是否应该允许多个线程共享一个ScriptEngine实例?这听起来像他们可以,但关键是通过Bindings可以发生的状态共享。不可变对象是你的朋友。
-
...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....或者每个线程应该构建一个短期实例吗?在我看来,想到这一点的最好方法是每次执行eval都是一个短暂的实例。
-
... 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.如果多个线程同时调用ScriptEngine.eval(...)会发生什么?如果我理解Rhino引擎对MULTITHREADING的正确反应,那么对于并发调用,ScriptEngine.eval应该没问题。
-
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.CompiledScript实例的相同问题JavaDocs声明“在随后的引擎执行脚本期间,可能会看到由执行CompiledScript引起的ScriptEngine状态的变化。” http://docs.oracle.com/javase/6/docs/api/javax/script/CompiledScript.html。因此,在您似乎试图最小化ScriptEngine实例数量的环境中,它们根本不会发出线程安全的声音。
-
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.
使用Invocable.getInterface(...)生成的接口实现的问题相同?你在这里独自一人。我不明白为什么或什么时候使用这种能力,这听起来像你可能在这里“跳鲨鱼”。如果你想深入研究脚本语言,我建议你放弃JavaScript并查看Groovy以获得更易编写脚本的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.据推测,放置在Bindings中的对象遵循Java的垃圾收集。那些没有在绑定中结束的对象的垃圾收集呢?如果它们最终没有绑定,我希望它们绑定到ScriptEngine并遵循其生命周期(基于我读过的文档)。汇集ScriptEngine实例听起来不是一个好主意。
#1
23
So I've run the experiment and the Rhino engine reports "Mozilla Rhino" is MULTITHREADED which the JavaDocs asserts
所以我运行实验并且Rhino引擎报告“Mozilla Rhino”是多线程的,JavaDocs断言
"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."
“MULTITHREADED” - 引擎实现在内部是线程安全的,脚本可以并发执行,尽管脚本执行对一个线程的影响可能对其他线程上的脚本可见。“
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: MULTITHREADEDengineName:AppleScriptEngine,THREADING:null engineName:Mozilla Rhino,THREADING:MULTHTHREADED
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.是否应该允许多个线程共享一个ScriptEngine实例?这听起来像他们可以,但关键是通过Bindings可以发生的状态共享。不可变对象是你的朋友。
-
...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....或者每个线程应该构建一个短期实例吗?在我看来,想到这一点的最好方法是每次执行eval都是一个短暂的实例。
-
... 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.如果多个线程同时调用ScriptEngine.eval(...)会发生什么?如果我理解Rhino引擎对MULTITHREADING的正确反应,那么对于并发调用,ScriptEngine.eval应该没问题。
-
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.CompiledScript实例的相同问题JavaDocs声明“在随后的引擎执行脚本期间,可能会看到由执行CompiledScript引起的ScriptEngine状态的变化。” http://docs.oracle.com/javase/6/docs/api/javax/script/CompiledScript.html。因此,在您似乎试图最小化ScriptEngine实例数量的环境中,它们根本不会发出线程安全的声音。
-
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.
使用Invocable.getInterface(...)生成的接口实现的问题相同?你在这里独自一人。我不明白为什么或什么时候使用这种能力,这听起来像你可能在这里“跳鲨鱼”。如果你想深入研究脚本语言,我建议你放弃JavaScript并查看Groovy以获得更易编写脚本的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.据推测,放置在Bindings中的对象遵循Java的垃圾收集。那些没有在绑定中结束的对象的垃圾收集呢?如果它们最终没有绑定,我希望它们绑定到ScriptEngine并遵循其生命周期(基于我读过的文档)。汇集ScriptEngine实例听起来不是一个好主意。