2010-01-14 18 views
5

Jeder versteht die Rhino-Javascript-Kontexte? Ich kann keine nützliche Dokumentation darüber finden. Mein Hauptproblem ist die Context.exit() (sollte wirklich cx.exit() sein), von dem ich verstehe, verlässt den Kontext, der mit dem gegenwärtigen Faden verbunden ist? Bedeutet das, dass ich verfolgen muss, was der Thread tut?Rhino Einbettung

Hauptthread:

Context cx; 
cx.evaluateReader(...) // load some function 
start thread 2 

Gewinde 2:

Object o= scope.get("methodname", scope); 
((Function)o).call(...) 

Ich plane nicht Multithreading auf zu tun, aber was ist, wenn die unterschiedlichen Setups, kommt aus verschiedenen Threads?

Antwort

13

Vom website docs:

Das Rhino Context Objekt verwendet wird Thread-spezifische Informationen über die Ausführungsumgebung zu speichern. Jedem Thread, der JavaScript ausführen soll, sollte ein und nur ein Kontext zugeordnet sein.

Mit anderen Worten, übergeben Sie nicht den Kontext zwischen Threads. Erstellen Sie einfach einen neuen Kontext im laufenden Thread. Mach dir keine Sorgen, Context.enter() mehr als einmal innerhalb eines Threads aufzurufen. Sie sind effektiv thread-lokale Variablen, die intern referenziert werden. So ruft Context.enter() im selben Thread ist sehr Licht.

wieder aus dem docs:

Diese Anrufe werden ordnungsgemäß funktionieren, auch wenn es bereits einen Kontext mit dem aktuellen Thread zugeordnet. Dieser Kontext wird zurückgegeben und ein interner Zähler wird erhöht. Nur wenn der Zähler Null erreicht, wird er vom Thread getrennt.

Ich persönlich nur dieser Code Konstrukt überall verwendet:

Context ctx = Context.enter(); 
try { 
    // do something with the ctx 
} finally { 
    Context.exit(); 
} 

In der Tat, in Groovy ich gepeitscht zusammen, um diese:

def withContext(Closure closure) { 
    Context ctx = Context.enter(); 
    try { 
     closure.call(ctx); 
    } finally { 
     Context.exit(); 
    } 
} 

und es dann Code passieren wie folgt aus:

withContext { Context ctx -> 
    ScriptableObject scope = ctx.initStandardObjects() 
    // now to do work with the scope and ctx. 
} 

Eine letzte Anmerkung. Der Bereich ist nicht an den Kontext gebunden und kann zwischen Threads beibehalten/weitergegeben werden.