Nashorn以线程安全的方式 [英] Nashorn in thread safe manner

查看:710
本文介绍了Nashorn以线程安全的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面我分享了我的代码,我试图使用线程安全的Nashorn作为脚本引擎来评估简单的数学公式。公式将像a * b / 2,其中& b将从地图对象中拾取。

Below I have shared my code in which I am trying to use thread safe Nashorn as scripting engine to evaluate simple mathematical formula. Formula will be like "a*b/2" where a & b will be picked up from map object.

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的一篇文章回答我们可以在线程之间共享脚本引擎对象,因为它们是线程安全的。

I need to know whether this approach will help making Nashorn thread safe for this use case. I read in Attila`s answer that we can share script engine objects between threads since they are thread safe.

对于绑定和eval,因为我们正在为每个创建新线程执行 evaluate ,每个线程都有自己的绑定对象的对象引用。那么完整的,这个实现是否是线程安全的?

For bindings and eval, since we are creating new thread for each execution of evaluate and each thread has its own object reference for bindings object. So in its entirety, will this implementation be thread safe?

推荐答案

我不认为这将是线程安全的,因为你'重新更改绑定,而另一个线程可能正在执行代码。你实际上不需要这样做;您可以创建一个全新的上下文,然后在该上下文中评估脚本。我会做这样的事情:

I don't think this will be threadsafe, since you're changing the bindings while another thread could potentially be executing code. You actually don't need to be doing this; you can just create a brand-new context and then evaluate the script in that context. I would do something like this:

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

现在每个脚本都在自己的上下文中进行评估。

Now each script gets evaluated in its own context.

这篇关于Nashorn以线程安全的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆