関数が共有オブジェクトを変更せずに引数のみを使用する場合、すべてのサーブレット要求に対して、同じNashornエンジンと1つの同じJavaScriptObject(JS関数の評価結果)を再利用することは可能ですか?コールと一緒に与えられた?次の例をご覧ください。Nashornで評価された関数は、異なるスレッドから再利用可能ですか?
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-functionはスレッドを節約しています。だから、コードは次のとおりです。あなたのインスタンスの
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);
}
}
表示される同時実行性の問題について具体的にお答えください。サーブレットのinitメソッドは同時に呼び出されません。したがって、スクリプトエンジンに問題はありません。評価されたスクリプト自体は、同時に呼び出されることもありますが、共有リソースを参照するものではありません。なぜこれが問題だと思いますか? – Gregor
これはStackoverflowの姉妹サイト、programmers.stackexchange.comのためのより良い質問かもしれません。私は簡単に言及します: 'doGet()'には確かに共有リソースがあります。それは 'script'変数です。 'init()'に関しては、 'init()'と 'doGet()'の間に同期があると言うJEEのドキュメントを指すことができますか?これは基本的なものです。これらの問題が見えない場合は、マルチスレッドの詳細を実際に知る必要があります。 – markspace
私が書いたとおり、スクリプトは同時に呼び出されます。それは共有されています。しかし、共有変数は必ずしもスレッドセーフではない。サーブレット要求はスレッドごとであるため、スクリプト自体は共有リソースに書き込まれません。だから私が必要とするのは、jsスクリプトを呼び出すことに関係する質問に対する答えです。 Nashornのドキュメンテーションはこれについて黙っています。 initメソッドに関しては、上記の改善された例では空であることがわかります。 – Gregor