스레드 안전이란 말은 어떤 속성에 set을 한 다음 get을 하기 전에 다른 무엇인가가 해당 속성에 set을 해서 내가 set한 속성 값을 그대로 get하지 못하는 경우를 말한다.
ServletContext에서도 스레드 안전이 보장되지 못한다.
즉 다음과 같이 코딩하게 되면 잘못된 결과가 리턴될 수도 있다는 말이다.
위와 같이 하면 ServletContext에 foo라는 속성에 22라는 값이, bar라는 속성에 42라는 값이 저장되게 되고, 화면 출력도 22, 42가 나오는 것이 정상이다.
하지만, 스레드 안전하지 못하기 때문에 중간에 다른 요청에 의해 위 메소드(doGet)가 실행되게 되거나, 다른 서블릿에 의해 foo 또는 bar의 속성이 변경되게 된다면 우리는 우리가 예상한 값을 보지 못할 수도 있다.
따라서 우리는 해당 Context에 lock을 걸어서 스레드 세이프 하게 만들어야 할 것이다.
해당 Context에 lock을 거는 방법은 아래와 같다.
synchronized block을 통해 해당 context에 접근하는 경우 lock을 건 다음 작업을 할 수 있다.
물론 이 방법도 완전히 안전한 것은 아니다.
해당 메소드 내에서 위와 같이 lock을 걸어서 사용한다 하더라도 synchronized block을 사용하지 않은 다른 메소드로 부터는 안전하지 않다.
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"));
}
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"));
}
}
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 |




Prev










