Nashorn 以线程安全的方式
Nashorn in thread safe manner
下面我分享了我的代码,我在其中尝试使用线程安全的 Nashorn 作为脚本引擎来评估简单的数学公式。公式类似于 "a*b/2",其中 a 和 b 将从地图对象中获取。
public class EvaluateFormulas {
@Autowired
NashornThreadPool pool;
private ScriptEngineManager factory;
private ScriptEngine engine;
private ScriptContext context;
@PostConstruct
public void setup() {
factory = new ScriptEngineManager();
engine = factory.getEngineByName("nashorn");
context = engine.getContext();
}
public void evaluate() {
pool.getThreadPoolExecutor().submit(new Runnable() {
@Override
public void run() {
Double result;
Bindings bind = engine.createBindings();
bind.putAll(map);
context.setBindings(bind, ScriptContext.GLOBAL_SCOPE);
try {
result = (Double) engine.eval(formula);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
我需要知道这种方法是否有助于使 Nashorn 线程在此用例中安全。我在 Attila 的 中读到我们可以在线程之间共享脚本引擎对象,因为它们是线程安全的。
对于绑定和评估,因为我们为每次执行 evaluate 创建新线程,并且每个线程都有自己的对象引用绑定对象。那么从整体上看,这个实现是线程安全的吗?
我认为这不是线程安全的,因为您正在更改绑定,而另一个线程可能正在执行代码。您实际上不需要这样做;您可以只创建一个全新的上下文,然后在该上下文中评估脚本。我会做这样的事情:
public void evaluate() {
pool.getThreadPoolExecutor().submit(new Runnable() {
@Override
public void run() {
Double result;
ScriptContext myContext = new SimpleScriptContext();
Bindings bindings = engine.createBindings();
bindings.putAll(map);
myContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
try {
result = (Double) engine.eval(formula, myContext);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
现在每个脚本都在其自己的上下文中进行评估。
下面我分享了我的代码,我在其中尝试使用线程安全的 Nashorn 作为脚本引擎来评估简单的数学公式。公式类似于 "a*b/2",其中 a 和 b 将从地图对象中获取。
public class EvaluateFormulas {
@Autowired
NashornThreadPool pool;
private ScriptEngineManager factory;
private ScriptEngine engine;
private ScriptContext context;
@PostConstruct
public void setup() {
factory = new ScriptEngineManager();
engine = factory.getEngineByName("nashorn");
context = engine.getContext();
}
public void evaluate() {
pool.getThreadPoolExecutor().submit(new Runnable() {
@Override
public void run() {
Double result;
Bindings bind = engine.createBindings();
bind.putAll(map);
context.setBindings(bind, ScriptContext.GLOBAL_SCOPE);
try {
result = (Double) engine.eval(formula);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
我需要知道这种方法是否有助于使 Nashorn 线程在此用例中安全。我在 Attila 的
对于绑定和评估,因为我们为每次执行 evaluate 创建新线程,并且每个线程都有自己的对象引用绑定对象。那么从整体上看,这个实现是线程安全的吗?
我认为这不是线程安全的,因为您正在更改绑定,而另一个线程可能正在执行代码。您实际上不需要这样做;您可以只创建一个全新的上下文,然后在该上下文中评估脚本。我会做这样的事情:
public void evaluate() {
pool.getThreadPoolExecutor().submit(new Runnable() {
@Override
public void run() {
Double result;
ScriptContext myContext = new SimpleScriptContext();
Bindings bindings = engine.createBindings();
bindings.putAll(map);
myContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
try {
result = (Double) engine.eval(formula, myContext);
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
现在每个脚本都在其自己的上下文中进行评估。