servlet 3.0 규범 의 비동기 적 특성 을 정확하게 이해 하 다.

5720 단어 자바
servlet 3.0 특성 에 대해 알 고 싶다 면 다음 ibm 의 글 을 추천 합 니 다.
https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/index.html#icomments
servlet 3.0 은 비동기 에 대한 지원 을 추 가 했 습 니 다. servlet 3.0 전에 클 라 이언 트 가 servlet 에 도착 하 라 고 요청 한 후에 servlet 는 보통 비교적 시간 이 걸 리 는 외부 작업 을 수행 합 니 다. 예 를 들 어 데이터 베이스 작업, I / O 작업, 크로스 네트워크 호출 등 은 현재 servlet 스 레 드 를 막 을 수 있 습 니 다. 현재 스 레 드 는 servlet 용기 (tomcat) 가 관리 하고 분배 합 니 다.용기 스 레 드 탱크 는 분 배 를 요청 하 는 스 레 드 에 일련의 servlet 자원 을 가지 고 있 습 니 다. 이 스 레 드 는 일련의 방법 (대부분 tomcat 내부 방법) 을 호출 하기 때 문 입 니 다. 방법 내부 에는 필터 가 있 는 웹 응용 프로그램 에서 모든 스 레 드 는 개인 적 인 filter Chain 대상 을 가지 고 있 을 수 있 습 니 다.차단 시간 이 너무 길 면 이 스 레 드 를 회수 할 수 없습니다. 자원 에 분 배 된 메모리 가 계속 점용 되 고 GC 에 의 해 회수 되 거나 Object pool 로 돌아 갈 수 없습니다. 또한 이 스 레 드 는 다른 클 라 이언 트 에 게 요청 할 수 없 기 때문에 어느 정도 에 병발 량 이 줄 어 들 수 있 습 니 다.
따라서 servlet 3.0 에서 servlet 에서 필요 한 작업 을 수행 한 후 (response. getWriter (). flush () 를 호출 할 수 있 습 니 다. 먼저 클 라 이언 트 의 일부 데 이 터 를 되 돌려 줍 니 다. flush () 방법 은 버퍼 의 데 이 터 를 출력 흐름 에 새로 고 칠 수 있 으 나 response. getWriter (). close () 방법 (close () 을 호출 할 수 없 기 때 문 입 니 다.방법 후 이 response 의 출력 흐름 이 종료 되 었 습 니 다). 또한 response 의 contentType 은 명시 적 으로 설정 되 어야 합 니 다 (그렇지 않 으 면 브 라 우 저 는 받 은 데이터 형식 을 모 르 고 일부 데 이 터 를 표시 하지 않 고 모든 데이터 가 올 때 까지 기다 리 는 것 을 선택 합 니 다). 소모 시간 이 비교적 큰 작업 을 다른 스 레 드 에 실행 할 수 있 습 니 다.servlet 용기 스 레 드 탱크 가 회수 할 수 있 도록 AsyncContext 컨 텍스트 를 전달 합 니 다.다른 스 레 드 는 실행 이 끝 난 후에 response. getWriter (). flush (), response. getWriter (). close () 작업 을 호출 하여 결 과 를 클 라 이언 트 에 게 되 돌려 줍 니 다.
servlet 3.0 규범 에 추 가 된 비동기 처리 지원 은 많은 사람들 이 오 류 를 이해 할 수 있 습 니 다. 예 를 들 어 이 글 과 평론 은 servlet 3.0 의 비동기 가 servlet 이 일부 결 과 를 클 라 이언 트 에 게 되 돌려 준 다음 에 나머지 결 과 를 클 라 이언 트 에 게 되 돌려 줄 수 있다 고 잘못 생각 합 니 다.이 문제 의 질문 자 처럼.
사실 이러한 반환 부분 결과 의 특성 은 servlet 2 에서 실 현 될 수 있 습 니 다. 출력 흐름 의 flush () 방법 을 여러 번 호출 하면 버퍼 의 데 이 터 를 출력 흐름 에 새로 고침 하면 출력 흐름 은 데 이 터 를 브 라 우 저 에 되 돌려 줍 니 다.이 때 response 의 contentType 이 명시 적 으로 설정 되면 브 라 우 저 는 데이터 (chrome 브 라 우 저) 를 일부 표시 합 니 다.즉, 실현 방식 은 flush () 방법 을 여러 번 호출 하고 마지막 으로 close () 방법 만 호출 하 는 것 이다.
일부 결 과 를 클 라 이언 트 에 게 되 돌려 주 는 것 은 비동기 가 아니 라 비동기 의 진정한 관심 사 는 배경 처리 방식 에 있다.일부 결 과 를 되 돌려 주면 배경 이 동기 화 될 수도 있 고 (flush 를 앞 당 겨 클 라 이언 트 체험 을 향상 시 킬 수도 있 고) 비동기 화 될 수도 있다.한편, servlet 3.0 규범 중의 이 보 는 클 라 이언 트 체험 에 주목 하 는 것 이 아니 라 일부 결 과 를 되 돌려 주 는 것 도 동기 화 될 수 있 기 때문이다.
writer.print("       ,           ");
writer.flush();//      
result = db.query();//       
writer.print(result);//      

그 진정한 목적 은 백 엔 드 를 비동기 적 으로 조작 하여 용기 가 관리 하 는 servlet 스 레 드 를 앞 당 겨 회수 하 는 것 이다.
주: servlet 2 에서 다른 스 레 드 를 만들어 response 를 전달 하고 servlet 에서 response 가 close 되 지 않 는 다 고 생각 했 습 니 다. 이것 도 배경 비동기 처 리 를 실현 할 수 있 지 않 습 니까?이 생각 을 증명 하기 위해 서 저 는 해 보 았 습 니 다. 결과 가 불안정 하고 데 이 터 를 잃 어 버 릴 수 있 습 니 다. 브 라 우 저 를 여러 번 새로 고침 하면 이 servlet 에 빠르게 접근 하면 Exception in thread "Thread-13" org.apache.tomcat.jni.Error: 20005: An invalid socket was returned at org.apache.tomcat.jni.Socket.sendbb(Native Method) 의 이상 을 보고 할 수 있 습 니 다. 이 유 는 servlet 스 레 드 가 방법 을 실행 한 후에 tomcat 는 자동 으로 response. close () 방법 을 사용 하여 다른 스 레 드 에서 출력 흐름 을 사용 할 때 입 니 다.클 라 이언 트 와 서버 의 연결 이 꺼 졌 습 니 다.
테스트 코드 는 다음 과 같 습 니 다:
@WebServlet(name = "noAsyncServlet",urlPatterns = "/noasync",asyncSupported = false)
public class NoAsyncServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final PrintWriter writer = resp.getWriter();
        writer.write("first");
        writer.write("second
"
); writer.flush(); new Thread(new Task(writer)).start(); writer.write("already give to another
"
); writer.flush(); } private class Task implements Runnable{ PrintWriter writer = null; public Task(PrintWriter writer) { this.writer = writer; } public void run() { writer.write("begin handle
"
); writer.flush(); try { Thread.sleep(1000); } catch (Exception e) { } writer.write("end handle
"
); writer.flush(); writer.close(); } } }

좋은 웹페이지 즐겨찾기