2015-01-01 13 views
5

Có thể tái sử dụng một và cùng một công cụ Nashorn và một và cùng JavaScriptObject, kết quả là đánh giá hàm JS, cho tất cả các yêu cầu servlet, nếu chức năng không thay đổi bất kỳ đối tượng được chia sẻ nào nhưng chỉ sử dụng đối số được đưa ra với cuộc gọi? Hãy xem ví dụ sau:Là một hàm được đánh giá trong Nashorn có thể tái sử dụng từ các luồng khác nhau?

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

là thread-an toàn không? Đây là một theo dõi để Reuse Nashorn ScriptEngine in Servlet

Edit: Tôi không chắc chắn những gì khác biệt này làm cho câu hỏi trong tầm tay, nhưng để tập trung vào những câu hỏi thú vị hơn, theo đó tình huống một cuộc gọi đến một đánh giá js-function là thread save, tôi đã tạo tất cả các trường cuối cùng. Vì vậy, mã này là:

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

Trả lời

1

Không ai trong số các biến thể hiện của bạn là safely published, vì vậy đó là một lớn "không" ngay tại đó. Ngoài ra không ai trong số các documentation nói rằng các lớp bạn sử dụng là thread an toàn, vì vậy mà không có một số tài liệu thêm nói khác nhau, bạn phải giả định rằng họ không phải là chủ đề an toàn.

Trả lời: không.

+0

Bạn có thể cụ thể hơn về các vấn đề tương tranh mà bạn thấy không? Phương thức init của servlet không được gọi đồng thời. Vì vậy, không nên có vấn đề với Script Engine. Bản thân kịch bản được đánh giá có thể được gọi đồng thời, nhưng nó không tham chiếu đến bất kỳ tài nguyên được chia sẻ nào. Tại sao bạn nghĩ điều này có vấn đề? – Gregor

+0

Đây có thể là câu hỏi hay hơn cho trang web chị em của Stackoverflow, programmers.stackexchange.com. Tôi sẽ đề cập một thời gian ngắn: chắc chắn có một tài nguyên được chia sẻ trong 'doGet()', đó là biến 'script'. Đối với 'init()', bạn có thể trỏ tới bất kỳ tài liệu JEE nào nói rằng có bất kỳ sự đồng bộ nào giữa 'init()' và 'doGet()' không? Đây là công cụ cơ bản, bạn thực sự cần phải tìm hiểu thêm về đa luồng nếu bạn không thể nhìn thấy những vấn đề này. – markspace

+1

Như tôi đã viết: kịch bản được gọi đồng thời. Nó được chia sẻ. Nhưng các biến được chia sẻ không cần thiết phải không an toàn. bản thân tập lệnh không ghi vào bất kỳ tài nguyên được chia sẻ nào, vì yêu cầu servlet là cho mỗi luồng. Vì vậy, những gì tôi cần là một câu trả lời cho câu hỏi, những gì có liên quan đến việc gọi một tập lệnh js. Tài liệu Nashorn im lặng về điều này. Về phương pháp init, bạn có thể thấy rằng nó trống trong ví dụ được cải thiện ở trên. – Gregor

Các vấn đề liên quan