相关疑难解决方法(0)

我应该为每个线程使用单独的ScriptEngine和CompiledScript实例吗?

我的程序使用Java Scripting API并且可以同时评估一些脚本.他们不使用共享脚本对象,绑定或上下文,但可以使用相同ScriptEngineCompiledScript对象.我看到Java 8中的Oracle Nashorn实现不是多线程的,ScriptEngineFactory.getParameter('THREADING')返回null文档所说的内容:

引擎实现不是线程安全的,不能用于在多个线程上并发执行脚本.

这是否意味着我应该ScriptEngine为每个线程创建一个单独的实例?此外,文档没有说明CompiledScript并发使用,但:

每个CompiledScript都与ScriptEngine相关联

可以假设CompiledScript线程安全依赖于相关ScriptEngine,即我应该CompiledScript为Nashorn的每个线程使用单独的实例.

如果我应该,对于这个(我认为非常常见的)案例,使用ThreadLocal,池或其他什么是适当的解决方案?

final String script = "...";
final CompiledScript compiled = ((Compilable)scriptEngine).compile(script);
for (int i=0; i<50; i++) {
    Thread thread = new Thread () {
        public void run() {
            try {
                scriptEngine.eval(script, new SimpleBindings ());  //is this code thread-safe?
                compiled.eval(new SimpleBindings ());  //and this?
            }
            catch (Exception e)  {  throw new RuntimeException …
Run Code Online (Sandbox Code Playgroud)

java multithreading jsr223 nashorn

52
推荐指数
2
解决办法
1万
查看次数

在Servlet中重用Nashorn ScriptEngine

我想在servlet中执行JavaScript.是否可以在所有servlet调用中重用相同的Scripting Engine?Servlet实例由多个线程共享.这是否需要为每个请求创建一个新的Scripting Engine?这将是一个令人无法接受的性能损失.例如,以下代码是否保存?

public class MyServlet extends HttpServlet {

private ScriptEngineManager factory;
private ScriptEngine engine;

@Override
public void init() throws ServletException {
    factory = new ScriptEngineManager();
    engine = factory.getEngineByName("nashorn");
}

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    try (PrintWriter writer = res.getWriter()) {
        ScriptContext newContext = new SimpleScriptContext();
        newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
        Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
        engineScope.put("writer", writer);
        Object value = engine.eval("writer.print('Hello, World!');", engineScope);
        writer.close();
    } catch (IOException | ScriptException ex) {
        Logger.getLogger(AsyncServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

如果这不安全,那么避免每个请求创建引擎的最佳方法是什么?使用引擎池? …

java servlets nashorn

13
推荐指数
1
解决办法
4036
查看次数

如何调用Nashorn CompiledScript中的方法?

我有以下代码可行:

ScriptEngine jsEngine = ScriptEngineManager.new().getEngineByName("nashorn");
jsEngine.eval("some script");

jsEngine.invokeMethod(jsEngine.eval("foo"), "bar");
Run Code Online (Sandbox Code Playgroud)

但我想使用预编译的脚本,所以每次我需要运行它时都不必评估脚本,所以我正在尝试;

ScriptEngine jsEngine = ScriptEngineManager.new().getEngineByName("nashorn");
CompiledScript compiledJS = jsEngine.compile("some script");
Run Code Online (Sandbox Code Playgroud)

但后来我不知道如何处理CompiledScript,我该如何调用方法呢?它显然没有实现除eval()以外的任何东西:https://docs.oracle.com/javase/8/docs/api/javax/script/CompiledScript.html

javascript java scriptengine nashorn

6
推荐指数
1
解决办法
5810
查看次数