当前位置: 首页 > 知识库问答 >
问题:

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

单修德
2023-03-14

如果函数不改变任何共享对象,而是只使用调用中给出的参数,那么是否可以对所有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);
    }
}

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

编辑:我不确定这对手头的问题有什么不同,但是为了关注更有趣的问题,在这种情况下,对一个已计算的js函数的调用是线程保存,我现在把所有字段都变成了最终的。所以代码是:

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

共有1个答案

浦毅
2023-03-14

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

回答:没有。

 类似资料:
  • 我们想在servlet中使用Nashorn。这个想法是使用ScriptEngine的单例实例,该实例在每次请求时都被重用。在每次请求时都会创建一个新的Engineering Scope绑定,并使用该绑定运行评估。然后清除绑定。没有共享对象被传递给绑定(只有servlet中的请求/响应对象)。 在servlet中,ScriptEngine的单例实例可能会在不同的线程中同时评估,这会正常工作还是会遇到

  • 问题内容: 可以安全地假设函数参数在Python中是从左到右求值的吗? 参考文献指出,这种情况会发生,但是也许有某种方法可以更改此顺序,这可能会破坏我的代码。 我想做的是为函数调用添加时间戳: 我知道我可以按顺序评估参数: 但是它看起来不太优雅,因此如果可以依靠它,我宁愿采用第一种方法。 问题答案: 是的,Python始终从左到右评估函数参数。 据我所知,这适用于任何逗号分隔的列表:

  • 我们的要求是同时写多个文件。我们正在使用spring批处理来编写文件,并且我们正在从不同的线程中启动spring批处理。每个线程都有自己的应用程序上下文。因此我们可以确保单例bean不会跨多个线程共享。下面是我的代码片段。 这就是我们调用spring批处理的方式。 ThreadPoolExecutor TPE=new ThreadPoolExecutor(10,10,1000000,TimeUni

  • 我在C 11应用程序中有长时间运行的功能,基本上是。我需要通知这个函数在不同线程中出现。要求: 可以随时上升。 应用程序最多只能在一个地方处理(也可以不处理)。 它不需要超快速执行,也不需要延迟执行 截至目前,我考虑了两种选择: 传递包含。然后在<code>sub_main</code>内定期轮询对象,以了解新的<code>情况</code>。轮询对象已从队列中删除。当应用程序决定不处理特定位置的

  • 问题内容: 我有一个网站,用户可以在其中输入数学方程式(表达式),然后根据该网站提供的数据(常数)对这些方程式进行评估。所需的数学运算,包括符号,算术运算,以及其他一些基本功能。一个示例方程式可以是: 可以使用Python来简单地做到这一点,但是众所周知,这会导致站点受损。做数学方程式评估的安全方法是什么? 如果选择使用Python本身来评估表达式,那么将存在任何限制Python的Python沙箱

  • 问题内容: 假设我通过创建共享对象并使用LD_PRELOAD首先加载它来替换函数。是否有可能使该功能的参数不同于原始库中的参数? 例如,如果我替换 pthread_mutex_lock ,这样它将代替参数 pthread_mutex_t 而是使用 pthread_my_mutex_t 。可能吗? 其次,除了函数之外,是否可以使用LD_PRELOAD更改结构声明?例如,可以向结构中增加一个字段。 问