java - Nashorn 以线程安全的方式

标签 java multithreading thread-safety nashorn scriptengine

下面我分享了我的代码,其中我尝试使用线程安全 Nashorn 作为脚本引擎来评估简单的数学公式。公式类似于“a*b/2”,其中 a 和 b 将从 map 对象中选取。

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 在此用例中线程安全。我在阿提拉的answer中读到我们可以在线程之间共享脚本引擎对象,因为它们是线程安全的。

对于绑定(bind)和评估,因为我们为每次执行评估创建新线程,并且每个线程都有自己的绑定(bind)对象的对象引用。那么总的来说,这个实现是线程安全的吗?

最佳答案

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

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

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

关于java - Nashorn 以线程安全的方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34165606/

相关文章:

java - Wildfly 无法注入(inject)值(value)?

java - BigDecimal 根据区域设置渲染小数点?

c++ - CreateFile,ReadDirectoryChanges 问题

python - 当在多线程中使用暴力破解时,它比单线程慢

java - 当我将 Collection<Foo> 传递到一个单独的类时,我应该锁定什么对象?

java - 静态函数的线程安全

java - 无法传递 String 和 Int var 来获取数组元素的值?

java - 如何用正确的参数喂养 appium?

python - QMutexLocker() 导致 UI 卡住

c++ - 返回 protected 数据时如何使用 lock_guard