2014-02-20 3 views
1

동일한 서블릿에 동일한 사용자가 동시에 실행될 수있는 ajax 메서드가 있습니다. 문제를 설명하기 위해 잘못된 단어를 사용하면 죄송합니다. 그러나 지금까지 이해하고있는 방법입니다 (스레딩에 대해 많이 알지 못합니다).스레드 간의 출력 스트림

은 어쨌든 여기가 두 번째 (동일한 ID에) 잘가 호출되는 1 시간을 작동하지만,이 방법은 아약스를 통해 호출되는 방법

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

그리고 그것은로 getWriter에 NullPointer를 (반환) 선. 나는 주변을 둘러 보았고 모두가 스레드에 대한 문제를 정확히 지적한 것 같습니다. 이제 더 문맥 조금

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

내가 그에게 응답을 할당 I 글로벌 바르에과 같이 선언 ThreadLocal 변수를 할당 서블릿이

doPost(request, response) 

에 들어가 매번 것

doPost() 메소드에서
Home.response.set(response); 

어떻게하면 getWriter() threadsafe를 만들까요?

답변

0

Tomcat은 모든 사용자 요청에 대해 새로운 요청 및 응답을 생성합니다. 그래서 그들은 이미 스레드 안전합니다 (당신이 들어가서 새 스레드를 생성하지 않는 한). 게다가, 당신이 "이드"를 통과하고 있는지 제대로 확인하고 있는지 확인하십시오. 나는 그것이 NullPointerException을 일으키는 getWriter()와 같은 줄에있는 "registro"객체라고 생각한다.

+0

정말 id가 "registro"가 null이 아니라고 확신합니다. NullPointerException을 throw합니다. 시간. – alexhg11

1

클래스 수준에 응답을 할당하는 이유가 확실하지 않습니다. ThreadLocal? 새로운 사용자 생성 요청마다 깨끗한 requestresponse 개체가 있습니다. getWriter 및 서블릿 클래스의 모든 메소드는 Java Servlet 사용에 대한 올바른 지침을 따르는 한 threadsafe입니다. Java Servlet의 일반적인 규칙은 클래스 수준 변수를 사용하지 않는 한 스레드로부터 안전하다는 것입니다.

ThreadLocal을 사용하는 대신 요청 및 응답 개체를 ajaxPartidas 메서드의 매개 변수로 전달한 다음 평소와 같이 호출해야합니다. 그래서 doPost 방법은 그냥 비즈니스 로직을 작성해야,이

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

} 

동시성 문제가 이미 서블릿 클래스 자체에 의해 처리됩니다 같을 것이다. Ajax와 함께 Java 서블릿을 사용하는 방법에 대한 자세한 내용은이 스레드에 대한 답변을 참조하십시오. https://stackoverflow.com/a/4113258/772385

+0

클래스 수준의 변수를 사용하고 문제가있는 경우 (다른 요청의 메시지가 있었지만 그 문제의 진정한 원인인지는 모르겠지만) threadlocal을 사용하십시오 (어쩌면 필요하지 않습니다). – alexhg11

+0

이 시나리오에서 나는 당신이 그것을 필요로하지 않을 것이라고 생각한다. 서블릿 API는 꽤 이상한 시나리오가 아니라면 자신 만의 동기화/스레드 컨트롤을하지 못하도록 고안되었습니다. – Durandal