2014-02-20 80 views
1

我的servlet上有一個ajax方法,可以同時爲同一個用戶運行。對不起,如果我用錯誤的詞來描述問題,但它是我迄今爲止的理解(不太瞭解線程)。線程之間的輸出流

反正這裏的方法

private void ajaxPartidas() throws ServletException, IOException { 
    //Variables necesarias 
    DataSource pool = (DataSource) session.get().getAttribute("pool"); 
    Recibo registro = null; 

    int id = -1; 
    try{ id = Integer.parseInt(request.get().getParameter("id"));}catch(NumberFormatException e){} 

    if(id > 0){ 
     registro = new Recibo(id); 
     if(!registro.obtener(pool)) 
      registro = null; 
     registro.setPartidas(Partida.obtenerRegistros(pool, registro.getId())); 
    } 

    response.get().setContentType("application/json"); 
    response.get().setHeader("Content-Type", "application/json; charset=utf-8");   
    response.get().getWriter().print((new Gson()).toJson(registro.getPartidas())); 
} 

這種方法正在通過AJAX調用時,它正常工作的第一時間就被調用,但第二次(上相同的ID)並返回上的getWriter一個空指針( )線。我環顧四周,每個人似乎都在向線索指出問題。現在語境更多一點點的將是每次該servlet在

doPost(request, response) 

進入我分配在全局變量聲明,像這樣一個ThreadLocal變量

private static ThreadLocal<HttpServletResponse> response = new ThreadLocal<>(); 

,我爲它分配響應

Home.response.set(response); 

在doPost()方法中。

我該如何去做getWriter()線程安全嗎?

回答

0

Tomcat爲每個用戶請求創建一個新的請求和響應。所以他們已經是線程安全的(除非你進入並創建一個新線程)。此外,請確保您傳遞「身份證」並正確設置。我認爲它是與導致NullPointerException的getWriter()在同一行上的「registro」對象。

+0

我非常確定它有id,「registro」不爲null,因爲它在第1次嘗試時起作用,然後引發NullPointerException 2nd時間周圍。 – alexhg11

1

不確定爲什麼要將類別分配給類級別ThreadLocal?每個新用戶生成的請求都有一個乾淨的requestresponse對象。 getWriter並且只要您遵循使用Java Servlet的正確指導原則,就可以使用servlet類中的所有方法。 Java Servlet的一般規則是,只要不使用類級變量,就是線程安全的。

而不是使用ThreadLocal,您需要將請求和響應對象作爲參數傳遞給您的ajaxPartidas方法,然後像平常一樣調用它。所以,你的doPost方法是這樣的

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     ajaxPartidas(request, response); 

} 

的併發問題由Servlet類本身已經處理,你只需要編寫業務邏輯。使用Ajax使用Java Servlet的更多細節,請參見此答案:https://stackoverflow.com/a/4113258/772385

+0

我確實使用了類級變量,並且曾經有過一個問題(它有另一個請求的消息,並不真正知道這是否是該問題的真正根源),但我想我應該研究更多關於何時使用threadlocal(也許我不需要它們)。 – alexhg11

+0

在這種情況下,我認爲你不需要它。 servlet API旨在讓您不必執行自己的同步/線程控制,除非您有一個非常奇怪的場景 – Durandal