2012-02-04 13 views
17

Estoy usando Rhino 1.6r2 a través de la API javax.script. Sé que el motor de Rhino afirma ser MULTITHREADED: "La implementación del motor es internamente segura para subprocesos y las secuencias de comandos pueden ejecutarse al mismo tiempo, aunque los efectos de la ejecución de la secuencia de comandos en un subproceso pueden ser visibles para las secuencias de comandos en otros subprocesos".Rhino y acceso concurrente a javax.script.ScriptEngine

Lo que me gustaría saber es, ¿bajo qué condiciones exactas serían visibles los efectos de la ejecución de un script para otro? En mi código, algunas veces reutilizo un objeto ScriptEngine, pero para cada ejecución creo un nuevo SimpleBindings y lo paso al eval(String, Bindings). Con esta disposición, ¿hay alguna forma de que el estado interno pueda filtrarse de una ejecución a otra? ¿Si es así, cómo?

There's a very informative answer here, pero no bastante dime lo que necesito saber.

+0

¿Está la unión de los mismos objetos? – wort

+0

Si estaba vinculando el mismo objeto para varias ejecuciones, obviamente sería visible para todas ellas. Pero no, no estoy haciendo eso. –

+0

¿Qué estás tratando de averiguar exactamente? Si está utilizando enlaces diferentes con diferentes objetos vinculados, ¿en qué otras cosas se refiere en términos de estado? – wort

Respuesta

3

Sí, JSR223 no especificó cómo deben vincularse las variables en el lenguaje de secuencia de comandos dado Bindings. Por lo tanto, es totalmente posible que los implementadores elijan almacenar variables de alcance global en la instancia del motor y reutilizarlo incluso teniendo en cuenta Bindings diferentes al evaluar el script.

Por ejemplo, de JRuby JSR223 de unión tiene un modo de trabajar de esta manera

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

El paquete javax.script es seguro para subprocesos, pero si su guión no lo sea, puede tener problemas de concurrencia. Las variables globales dentro de la secuencia de comandos son visibles para todas las discusiones. Por lo tanto, evite el uso de variables globales dentro de sus funciones de Javascript

Me encuentro con este problema en este momento. Mi javascript es el siguiente:

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

Y yo estoy corriendo dentro de una ThreadPool (4) 10.000 veces, e imprimir el resultado.

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

Este es un pedazo de la salida:

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 
Cuestiones relacionadas