2015-01-01 5 views
5

関数が共有オブジェクトを変更せずに引数のみを使用する場合、すべてのサーブレット要求に対して、同じ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); 
    } 
} 

答えて

1

なしの変数がsafely published,あるので、それはすぐそこに「ノー」ビッグません。また、documentationのどれも、あなたが使っているクラスはスレッドセーフであると言っているので、別のドキュメントがなければスレッドセーフではないと仮定する必要があります。

回答:いいえ。

+0

表示される同時実行性の問題について具体的にお答えください。サーブレットのinitメソッドは同時に呼び出されません。したがって、スクリプトエンジンに問題はありません。評価されたスクリプト自体は、同時に呼び出されることもありますが、共有リソースを参照するものではありません。なぜこれが問題だと思いますか? – Gregor

+0

これはStackoverflowの姉妹サイト、programmers.stackexchange.comのためのより良い質問かもしれません。私は簡単に言及します: 'doGet()'には確かに共有リソースがあります。それは 'script'変数です。 'init()'に関しては、 'init()'と 'doGet()'の間に同期があると言うJEEのドキュメントを指すことができますか?これは基本的なものです。これらの問題が見えない場合は、マルチスレッドの詳細を実際に知る必要があります。 – markspace

+1

私が書いたとおり、スクリプトは同時に呼び出されます。それは共有されています。しかし、共有変数は必ずしもスレッドセーフではない。サーブレット要求はスレッドごとであるため、スクリプト自体は共有リソースに書き込まれません。だから私が必要とするのは、jsスクリプトを呼び出すことに関係する質問に対する答えです。 Nashornのドキュメンテーションはこれについて黙っています。 initメソッドに関しては、上記の改善された例では空であることがわかります。 – Gregor

関連する問題