java - Nashorn 中的评估函数是否可从不同线程重用?

标签 java javascript multithreading servlets nashorn

是否有可能为所有 servlet 请求重用同一个 Nashorn 引擎和同一个 JavaScriptObject,它作为 JS 函数的评估结果,如果该函数不更改任何共享对象而仅使用调用时给出的参数?看下面的例子:

public class MyServlet extends HttpServlet {

private ScriptEngineManager factory;
private ScriptEngine engine;
private ScriptObjectMirror script;

@Override
public void init() throws ServletException {
    try {
        factory = new ScriptEngineManager();
        engine = factory.getEngineByName("nashorn");
        script = (ScriptObjectMirror)engine.eval("function(writer) {writer.print('Hello, World!');}");
    } catch (ScriptException ex) {
        Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    try (PrintWriter writer = res.getWriter()) {
        script.call(null, writer);
        writer.close();
    } catch (IOException ex) {
        Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}

这是线程安全的吗? 这是 Reuse Nashorn ScriptEngine in Servlet 的后续行动

编辑: 我不确定这对手头的问题有什么不同,但为了关注更有趣的问题,在什么情况下调用已评估的 js 函数是线程保存,我现在将所有字段设置为 final。所以代码是:

public class MyServlet extends HttpServlet {

final private ScriptEngineManager factory;
final private ScriptEngine engine;
final private ScriptObjectMirror script;

public MyServlet() {
    factory = new ScriptEngineManager();
    engine = factory.getEngineByName("nashorn");
    ScriptObjectMirror _script = null;
    try {
        _script = (ScriptObjectMirror) engine.eval("function(writer) {writer.print('Hello, World!');}");
    } catch (ScriptException ex) {
        Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
    script = _script;
}

@Override
public void init() throws ServletException {
}

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    try (PrintWriter writer = res.getWriter()) {
        script.call(null, writer);
        writer.close();
    } catch (IOException ex) {
        Logger.getLogger(MyServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}

最佳答案

你的实例变量都不是 safely published,所以这是一个很大的“不”。也没有 documentation说您使用的类是线程安全的,因此如果没有进一步的文档说明不同,您必须假设它们不是线程安全的。

回答:没有。

关于java - Nashorn 中的评估函数是否可从不同线程重用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27732654/

相关文章:

java - 如何在 Linux (Centos 7) shell 上在后台正确运行 Spring Boot Batch 应用程序?

java - Spring + JPA/Hibernate 不保存多对多映射

javascript - 如何使用 Moment.js 更改日期?

java - Java 中的同步 - Thinking in Java 示例

C 读取套接字偶尔发生变化

java - EJB 和持久性异常

java - Google 集合 - 来自 collections.filter 的可修改迭代器?

javascript - 我必须用 Zapier 替换 Code 上的一些特殊字符

javascript - nodejs promise 数组,我该怎么做?

java - 在 ViewRootImpl.java 中创建线程