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

Gre*_*gor 5 javascript java multithreading servlets nashorn

如果函数不更改任何共享对象但仅使用给定的参数,是否可以重用同一个Nashorn引擎和同一个JavaScriptObject(对于所有servlet请求,作为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是线程安全的吗?这是在Servlet中重用Nashorn ScriptEngine的后续内容

编辑: 我不确定这对于手头的问题有什么不同,但是要关注更有趣的问题,在哪种情况下调用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

mar*_*ace 1

您的实例变量都没有安全发布,因此这是一个很大的“不”。此外,没有任何文档表明您使用的类是线程安全的,因此如果没有进一步的文档说明不同,您必须假设它们不是线程安全的。

答:不。