자바 Servlet, Struts, springMVC 의 스 레 드 안전 문제

4038 단어
현재 주류 자바 의 전단 프레임 워 크 는 struts 1, struts 2, springmvc 그리고 가장 근본 적 인 servlet 입 니 다.
며칠 전에 한 친구 가 나 에 게 이 방면 의 문 제 를 물 어서 한 번 연구 했다.
1. struts 1 에 대하 여:
Struts 1 에서 사용 하 는 Action Servlet 은 하나의 예 입 니 다. 이 servlet 에서 모든. do 요청 을 처리 합 니 다.RequestProcessor 도 일례 다.
RequestProcessor 의 processAction Create 방법:
/**
  * <p>Return an <code>Action</code> instance that will be used to process
  * the current request, creating a new one if necessary.</p>
  *
  * @param request  The servlet request we are processing
  * @param response The servlet response we are creating
  * @param mapping  The mapping we are using
  * @return An <code>Action</code> instance that will be used to process
  *         the current request.
  * @throws IOException if an input/output error occurs
  */
 protected Action processActionCreate(HttpServletRequest request,
     HttpServletResponse response, ActionMapping mapping)
     throws IOException {
     // Acquire the Action instance we will be using (if there is one)
     String className = mapping.getType();
     if (log.isDebugEnabled()) {
         log.debug(" Looking for Action instance for class " + className);
     }
     Action instance;
     // 这个同步快保证了Action的单例
     synchronized (actions) {
         // Return any existing Action instance of this class
         instance = (Action) actions.get(className);
         if (instance != null) {
             if (log.isTraceEnabled()) {
                 log.trace("  Returning existing Action instance");
             }
             return (instance);
         }
         // Create and return a new Action instance
         if (log.isTraceEnabled()) {
             log.trace("  Creating new Action instance");
         }
         try {
             instance = (Action) RequestUtils.applicationInstance(className);
             // Maybe we should propagate this exception
             // instead of returning null.
         } catch (Exception e) {
             log.error(getInternal().getMessage("actionCreate",
                     mapping.getPath()), e);
             response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                 getInternal().getMessage("actionCreate", mapping.getPath()));
             return (null);
         }
         actions.put(className, instance);
         if (instance.getServlet() == null) {
             instance.setServlet(this.servlet);
         }
     }
     return (instance);
 }

결 과 를 통 해 알 수 있 듯 이 단일 사례 인 만큼 인 스 턴 스 변 수 를 사용 할 때 스 레 드 안전 문제 가 발생 할 수 있 습 니 다.
2. struts 2 에 대하 여
우 리 는 우리 가 struts 2 를 사용 할 때 모두 actionContext 를 사용 한 다 는 것 을 안다.모두 안에 있 는 인 스 턴 스 변 수 를 사용 하여 struts 2 를 대상 으로 자동 으로 일치 시 킵 니 다.스 레 드 안전 이 아니라면 다 끝 났 습 니 다.그래서 struts 2 는 반드시 라인 이 안전 해 야 한다.요청 을 처리 할 때마다 struts 는 대상 을 예화 하기 때문이다.이렇게 하면 라인 안전 에 문제 가 없 을 것 이다.
읊다, 읊조리다action 을 단일 모드 로 설정 하면 문제 가 발생 합 니 다.action 을 prototype 형식 으로 설정 할 수 있 습 니 다. 또 하나의 방법 은 역할 영역 을 설정 하 는 것 입 니 다 (구체 적 으로 실험 하지 않 았 습 니 다)
참조 소스
3. SpringMVC 에 대하 여
SpringMVC 의 contrller 는 기본적으로 단일 모드 이기 때문에 다 중 스 레 드 가 동시에 발생 하 는 문제 도 있 습 니 다.
참조 코드:
@RequestMapping("/user")
@Controller
Class UserController
{
    @Resource
    UserService userService;

    @RequestMapping("/add")
    public void testA(User user){
        userService.add(user);
    }

    @RequestMapping("/get")
    public void testA(int id){
        userService.get(id);
    }
}

@Service("userService")
Class UserService{

    public static Map<Integer,User> usersCache = new HashMap<String,User>();

    public void add(User user){
        usersCache.put(user.getId(),user);
    }

    public void get(int id){
        usersCache.get(id);
    }

}

usersCache 는 비 스 레 드 안전 합 니 다.
해결 방법:
1) 데이터 동기 화
2) 구성원 인 스 턴 스 변 수 를 사용 하지 않 습 니 다.
3) 읽 기 전용 데이터 사용
참고 글:
Servlet 스 레 드 안전성 문 제 를 깊이 연구 하 다.
Struts 스 레 드 보안 문제
Servlet 스 레 드 안전성 문 제 를 깊이 연구 하 다.

좋은 웹페이지 즐겨찾기