问题描述
我正在Nashorn中尝试加载和评估多线程脚本并获得一些令人震惊的行为:
I'm experimenting with multi-threaded scripts loading and evaluation in Nashorn and get kind of shocking behavior:
// having some object o loaded in another thread
print(o.constructor === o.constructor); // false
print(o.constructor === Object); // false as well
print(o.foo === o.foo); // true - OK
如何在单个脚本引擎中实现这一点?上面的 o
只是使用对象文字表示法创建的对象(在另一个线程中)。打印 o.constructor
给出通常的函数Object(){[native code]};
。
How can this be possible within single script engine? o
above is just an object created using object literal notation (in another thread). Printing o.constructor
gives usual function Object() { [native code] };
.
同时:
print({}.constructor === {}.constructor); // true
任何想法?
更新
事实证明这与多线程完全无关。有关详细信息,请参阅下面的答案。
It turned out this was unrelated to multi-threading at all. See my answer below for details.
推荐答案
事实证明,这与多线程无关。这是一个简单的Scala程序,可以重现问题:
It turned out this does not relate to multi-threading at all. Here is a simple Scala program which reproduces the problem:
object Test extends App {
val engine = new ScriptEngineManager().getEngineByName("nashorn")
var o = engine.eval("({ foo: 'bar' })")
var result = engine.eval("(o.constructor === o.constructor)", new SimpleBindings() {
put("o", o)
})
print(result) // false
}
我错误地使用绑定
参数。相反,我应该采用现有的绑定
并就地更新它们。我仍然不相信这会导致 o.constructor === o.constructor
为假,但至少它现在有效。更正版本:
I was using bindings
parameter incorrectly. Instead, I should take existing bindings
and update 'em in-place. I'm still not convinced this should result in o.constructor === o.constructor
to be false, but at least it works now. Corrected version:
object Test extends App {
val engine = new ScriptEngineManager().getEngineByName("nashorn")
var o = engine.eval("({ foo: 'bar' })")
val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE)
bindings.put("o", o)
var result = engine.eval("(o.constructor === o.constructor)", bindings)
print(result) // true
}
这篇关于多线程Nashorn:o.constructor === o.constructor给出false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!