Czy jest możliwe ponowne użycie jednego i tego samego silnika Nashorn i jednego i tego samego obiektu JavaScriptObject, który jest wynikiem oceny funkcji JS dla wszystkich żądań serwletów, jeśli funkcja nie zmienia żadnego obiektu udostępnionego, ale używa tylko argumentów biorąc pod uwagę połączenie? Spójrz na następujący przykład:Czy funkcja oceniana w Nashorn jest wielokrotnego użytku z różnych wątków?
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);
}
}
Czy to wątek bezpieczne? To jest kontynuacją Reuse Nashorn ScriptEngine in Servlet
Edit: Nie jestem pewien, co różnica to sprawia, że na pytanie pod ręką, ale skupić się na bardziej interesujące pytanie, w jakich okolicznościach wezwanie do Oceniona js-function jest zapisem wątku, teraz wszystkie pola są już ostateczne. Więc kod jest:
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);
}
}
Mógłbyś być bardziej szczegółowy na temat problemów dotyczących współbieżności, które widzisz? Metoda init serwletu nie jest wywoływana jednocześnie. Dlatego nie powinno być problemu z mechanizmem skryptowym. Sam ewaluowany skrypt może być wywoływany jednocześnie, ale nie odnosi się do żadnego udostępnionego zasobu. Dlaczego uważasz, że jest to problematyczne? – Gregor
To może być lepsze pytanie dla siostrzanej strony Stackoverflow, programmers.stackexchange.com. Wspomnę krótko: w '' DoGet() 'jest z pewnością wspólny zasób, jest to zmienna' script'. Co do 'init()', czy możesz wskazać na dowolną dokumentację JEE, która mówi, że istnieje jakakolwiek synchronizacja między 'init()' a 'doGet()'? To są podstawowe rzeczy, naprawdę musisz dowiedzieć się więcej o wielowątkowości, jeśli nie widzisz tych problemów. – markspace
Jak napisałem: skrypt jest wywoływany równolegle. Jest udostępniony. Ale wspólne zmienne nie są koniecznie potrzebne, a nie bezpieczne dla wątków. sam skrypt nie zapisuje do dowolnego zasobu udostępnionego, ponieważ żądanie serwletu jest dla danego wątku. Potrzebuję więc odpowiedzi na pytanie, co wiąże się z wywołaniem skryptu js. Dokumentacja Nashorn milczy na ten temat. Jeśli chodzi o metodę init, możesz zobaczyć, że jest ona pusta w moim poprawionym przykładzie powyżej. – Gregor