'스레드 세이프'에 해당하는 글 1건

스레드 안전이란 말은 어떤 속성에 set을 한 다음 get을 하기 전에 다른 무엇인가가 해당 속성에 set을 해서 내가 set한 속성 값을 그대로 get하지 못하는 경우를 말한다.
ServletContext에서도 스레드 안전이 보장되지 못한다.
즉 다음과 같이 코딩하게 되면 잘못된 결과가 리턴될 수도 있다는 말이다.

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws IOException, ServletException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
       
        out.println("test context attributes<br>");
       
        getServletContext().setAttribute("foo", "22");
        getServletContext().setAttribute("bar", "42");
       
        out.println(getServletContext().getAttribute("foo"));
        out.println(getServletContext().getAttribute("bar"));
    }

위와 같이 하면 ServletContext에 foo라는 속성에 22라는 값이, bar라는 속성에 42라는 값이 저장되게 되고, 화면 출력도 22, 42가 나오는 것이 정상이다.
하지만, 스레드 안전하지 못하기 때문에 중간에 다른 요청에 의해 위 메소드(doGet)가 실행되게 되거나, 다른 서블릿에 의해 foo 또는 bar의 속성이 변경되게 된다면 우리는 우리가 예상한 값을 보지 못할 수도 있다.
따라서 우리는 해당 Context에 lock을 걸어서 스레드 세이프 하게 만들어야 할 것이다.
해당 Context에 lock을 거는 방법은 아래와 같다.

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws IOException, ServletException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
       
        out.println("test context attributes<br>");
       
        synchronized (getServletContext()) {
            getServletContext().setAttribute("foo", "22");
            getServletContext().setAttribute("bar", "42");
           
            out.println(getServletContext().getAttribute("foo"));
            out.println(getServletContext().getAttribute("bar"));
        }
    }

synchronized block을 통해 해당 context에 접근하는 경우 lock을 건 다음 작업을 할 수 있다.
물론 이 방법도 완전히 안전한 것은 아니다.
해당 메소드 내에서 위와 같이 lock을 걸어서 사용한다 하더라도 synchronized block을 사용하지 않은 다른 메소드로 부터는 안전하지 않다.

신고

'Java > Servlet & JSP' 카테고리의 다른 글

Cookie 사용하기  (0) 2009.02.02
Session 관리  (0) 2009.01.30
스레드 안전한 ServletContext 만들기  (1) 2009.01.29
ServletContext 이용하기  (2) 2009.01.23
ServletConfig 이용하기  (0) 2009.01.22
MVC 식 Servlet 사용  (0) 2009.01.21

WRITTEN BY
체리필터
프로그램 그리고 인생...

받은 트랙백이 없고 , 댓글 하나 달렸습니다.
  1. Servlet 내에서 그런식의 Synchronized 를 쓴다는게 좀 이상하네요 .. 물론 굳이 예제를 보여주기 위해서라면 이해는 갑니다만 ..
    그럼 혹 이런 방식은 어떤지
    현재 쓰레드 ID 를 가져와 [ThreadId].foo 를 넣어서 다시 그이름으로 찾는 다면 좀더 안전 하지 않을까 합니다
    다른 쓰레드 접근 걱정도 문제 없고 동기화 블록으로 생기는 보틀넥도 줄이고 ..
    그럼 ..
secret