[펌글] 스레드 안전한 ServletContext 만들기

By | 8월 3, 2009

- 출처 : http://www.4te.co.kr/544 -

스레드 안전이란 말은 어떤 속성에 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을 사용하지 않은 다른 메소드로 부터는 안전하지 않다.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments