2012-02-04 40 views
17

私はRhino 1.6r2をjavax.script API経由で使用しています。 RhinoエンジンはMULTITHREADED:と主張しています。「エンジン実装は内部的にはスレッドセーフで、スクリプトは同時に実行されるかもしれませんが、あるスレッドでのスクリプト実行の影響は他のスレッド上のスクリプトで見えるかもしれません。Rhinoとjavax.script.ScriptEngineへの同時アクセス

私が知りたいのは、正確な条件の下で、あるスクリプトの実行の影響が別のものに見えるかどうかです。私のコードでは、ときどきScriptEngineオブジェクトを再利用しますが、実行するたびに新しいSimpleBindingsを作成してeval(String, Bindings)に渡します。この配置では、ある実行から別の実行に内部状態が漏れる可能性がありますか?もしそうなら、どうですか?

There's a very informative answer hereですが、かなり私に知っておくべきことを教えてください。

+0

あなたは同じオブジェクトを結合していますか? – wort

+0

複数の実行のために同じオブジェクトをバインドしていた場合は、明らかにすべてのオブジェクトで表示されます。しかし、いいえ、私はそれをやっていません。 –

+0

正確に何を把握しようとしていますか?バインドされたオブジェクトが異なる別のバインディングを使用している場合は、それ以外の状態に関して何が関係していますか? – wort

答えて

3

はい、JSR223では、スクリプト言語の変数を指定してBindingsとバインドする方法を指定していませんでした。したがって、インプリメンターがグローバルスコープ変数をエンジンインスタンスに格納することを選択し、スクリプトを評価するときに別のBindingsを与えてもそれを再利用することは完全に可能です。例えば

は、JRubyのJSR223結合は、このよう

import javax.script.ScriptContext; 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 
import javax.script.ScriptException; 
import javax.script.SimpleScriptContext; 

public class Jsr223Binding { 


    private Jsr223Binding() throws ScriptException { 
     System.setProperty("org.jruby.embed.localvariable.behavior", "transient"); 
     ScriptEngineManager manager = new ScriptEngineManager(); 
     ScriptEngine engine = manager.getEngineByName("jruby"); 
     ScriptContext ctx1 = new SimpleScriptContext(); 
     ScriptContext ctx2 = new SimpleScriptContext(); 
     engine.eval("$foo = 5\nputs $foo", ctx1); 
     engine.eval("puts $foo", ctx2); 
    } 

    public static void main(String[] args) throws ScriptException { 
     new Jsr223Binding(); 
    } 
} 
4

持つjavax.scriptパッケージは、スレッドセーフであるで働く一方のモードを持っていますが、あなたのスクリプトがない場合は、並行性の問題を持つことができます。 スクリプト内のグローバル変数は、すべてのスレッドに表示されます。だから、あなたのJavaScript関数内でグローバル変数を使用しないでください

私はこの問題に直面しています。私のjavascriptは次の通りです:

function run(){ 
    regex = 0; 
    regex += 1; 
    return regex; 
} 

そして私はThreadPool(4)の10.000倍で実行し、結果を出力しています。

for (int i = 0; i <= 10000; i++){ 
     executor.submit(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Double result = (Double) invocable.invokeFunction("run"); 
        System.out.println(result); 
       } catch (Exception e) {} 
      } 
     }); 
    } 

これは出力の一部です:

1.0 
2.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
1.0 
2.0 
1.0 
1.0 
0.0 
関連する問題