서블릿의 각 인스턴스와 서블릿의 각 서블릿 스레드의 차이점은 무엇입니까? [복제]
이 질문에 이미 답변이 있습니다.
서블릿 클래스의 여러 인스턴스가 있습니까? 내가 "서블릿의 각 인스턴스"를 들었을 때 누구든지 이것에 대해 자세히 설명 할 수 있습니까?
Servlet 컨테이너가 시작되면 다음을 수행합니다.
- 읽습니다
web.xml
; - 클래스 경로에서 선언 된 서블릿을 찾습니다. 과
- 각 Servlet을 한 번만 로드하고 인스턴스화합니다 .
대략 다음과 같습니다.
String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // Similar to a map interface.
이러한 서블릿은 메모리에 저장되며 요청 URL이 서블릿의 관련 .NET과 일치 할 때마다 재사용됩니다 url-pattern
. 그러면 서블릿 컨테이너는 다음과 유사한 코드를 실행합니다.
for (Entry<String, HttpServlet> entry : servlets.entrySet()) {
String urlPattern = entry.getKey();
HttpServlet servlet = entry.getValue();
if (request.getRequestURL().matches(urlPattern)) {
servlet.service(request, response);
break;
}
}
GenericServlet#service()
의 턴은의 결정 doGet()
, doPost()
에 따라 호출, 등 HttpServletRequest#getMethod()
.
servletcontainer는 모든 요청에 대해 동일한 서블릿 인스턴스 를 재사용합니다 . 즉, 서블릿은 모든 요청 간에 공유 됩니다 . 그렇기 때문에 스레드 안전 방식으로 서블릿 코드를 작성하는 것이 매우 중요합니다. 실제로 간단합니다. 요청 또는 세션 범위 데이터를 서블릿 인스턴스 변수로 할당 하지 말고 메서드 로컬 변수로 할당하면됩니다. 예
public class MyServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
아니요, 여러 클라이언트의 여러 요청에 재사용되는 서블릿의 인스턴스는 하나뿐입니다. 이것은 두 가지 중요한 규칙으로 이어집니다.
- 컨텍스트 매개 변수에서 가장 자주 가져 오는 애플리케이션 전체 값을 제외하고 서블릿에서 인스턴스 변수를 사용하지 마십시오.
synchronized
서블릿에서 메소드 를 만들지 마십시오.
(서블릿 필터 및 jsps에도 동일 함)
자바 서블릿 사양 버전 3.0 (pp. 6-7)에 따르면 서블릿이 단일 스레드 모델을 구현하지 않는 한 JVM 당 선언 당 하나의 인스턴스가 있습니다.
이미 몇 가지 좋은 답변이 있지만 분산 환경에 배포 된 Java 웹 애플리케이션에 대해 언급 한 사람은 없습니다. 이것은 실제로 단일 서블릿의 여러 인스턴스가 생성되는 실용적인 시나리오입니다. 분산 환경에서는 요청을 처리 할 머신 클러스터가 있으며 요청은 이러한 머신 중 하나로 이동할 수 있습니다. 이러한 각 머신은 요청을 처리 할 수 있어야하므로 모든 머신은 JVM에 MyAwesomeServlet의 인스턴스가 있어야합니다.
So, the correct statement would be there is only one instance per JVM for every servlet, unless it implements SingleThreadModel.
SingleThreadModel in simple words says that you have to have only one thread per instance of Servlet, so basically you need to create one instance per coming request to handle it, which basically kills the whole concept of handling requests in a parallel fashion and isn't considered a good practice as the servlet object creation and initialization takes up time before it's ready to process the request.
There can not be multiple instances of servlet class. Even when there is one instance of the servlet, it is able to handle multiple requests. So it is wise not to use class level variables.
For those that know real JavaScript (not just a library of it), Servlets can be viewed as function objects. As functional objects, the main task of them is to do something, instead of to store some information in their chests. There is no need to instantiate more than one instance of every such functional object, with the same rationale that Java class methods are shared among all instances of that class.
'code' 카테고리의 다른 글
Apache를 다시 시작할 때 "make_sock : 주소 [::] : 443에 바인딩 할 수 없습니다"(trac 및 mod_wsgi 설치) (0) | 2020.09.20 |
---|---|
현재 PowerShell 실행 파일을 얻으려면 어떻게해야합니까? (0) | 2020.09.20 |
EditText의 포커스 테두리 제거 (0) | 2020.09.20 |
UIScrollView : 수평으로 페이징, 수직으로 스크롤? (0) | 2020.09.20 |
진동 권한은 어떻게 요청하나요? (0) | 2020.09.20 |