2016-08-11 121 views
1

今天,我已經使用ScriptContext中創建線程安全跨多個線程使用單個犀牛引擎,但它是相當昂貴的創建許多情況下,因爲各方面也必須EVAL我的基地JS庫。克隆/複製SimpleScriptContext

有沒有辦法複製/克隆一個ScriptContext中(SimpleScriptContext)已經有一些基礎的綁定,一旦被複制,添加一些附加綁定到它,同時保持線程安全?

或者,有沒有辦法做到這一點獲得更好的性能的另一種方式,也許克隆/複製綁定和使用context.setBindings()?或者克隆/複製Bindings對象的基礎地圖並使用SimpleBindings(map)構造函數?

+0

我試過使用SimpleBindings複製構造函數從現有的Bindings和使用context.setBindings開始,但結果不是線程安全的。 – Aaron

+0

SimpleBindings沒有拷貝構造函數。它只是使用您傳遞的映射實例來存儲映射。它沒有有效地複製它。 – NishM

回答

0

您可以在每次執行前複製綁定並將其添加到全局上下文中,然後添加到ScriptEngine中。這意味着必須有一個綁定的全局副本,它具有所有JavaScript執行所需的通用映射。這些綁定在每次執行之前都會複製並用於上下文引擎組合中,以便本地映射不會干擾全局綁定內的映射。

話雖如此,我會使用一個引擎來服務所有的線程,因爲犀牛的ScriptEngine不是線程安全的避免。我會建議每個線程使用一個引擎。

有堆棧溢出職位,不要說是ScriptEngine的逸岸線程,但我已經在使用一個引擎,複製到它的每一個電話綁定面臨一些嚴重的串擾問題。

另請注意,Bindings.copyAll()不會確保JavaScript對象之間的一致行爲。在您的JavaScript代碼中,您可能會遇到問題,同時JSON.string在作爲複製映射的一部分的對象。

編輯:從評論這個答案來自@DennisKrøger,ScriptContext中的實例應該被用來代替綁定克服串擾。

+1

Nashorn ScriptEngine應該(並且以我的經驗)是線程安全的。您可能直接使用綁定而不是使用綁定設置的上下文。 至少這就是我所做的,直到我切換到使用上下文爲止,我遇到了可怕的線程問題。 –

+0

@DennisKrøger謝謝,但不幸的是,像我們一樣,我們也很遲才意識到使用上下文是要走的路。目前,我們通過將一些對象聲明爲ThreadLocal來克服線程安全問題。長期和永久性的解決辦法是改爲處理上下文。 – NishM