실행중인 동안 새로운 스레드에서 다른 객체 메소드를 시작하는 Java 서블릿을 개발 중입니다. 이러한 스레드는 jobServ와 같은 특정 서블릿 인스턴스를 설명하는 변수에 액세스해야합니다. 이런 이유로 나는 jobId 변수를 정적으로 선언했다. 서블릿 생성자는 각 서블릿 인스턴스 (호출)에 대해이 값을 계산합니다. 서블릿이 동시에 몇 번 호출되면 정적 jobId 변수가 호출간에 공유되므로 일부 스레드가 잘못된 jobId를 얻거나 각 호출에 대해 한 번씩 계산됩니다. 시작된 특정 서블릿은이 특정 서블릿에 대해 계산 된 jobId를 사용합니다 (작동 방식). 어떤 아이디어? 대단히 감사합니다!
- 답변 # 1
- 답변 # 2
static
모든 인스턴스가 동일한 값에 액세스 함을 의미합니다.
따라서 서블릿에 연결된 모든 사용자는 동일한 값에 액세스합니다. 2 명 이상의 사용자가 서로 연결되어 있으면 jobId가 잘못되었을 수 있습니다.각 연결마다 자신의 가치를 얻어 다른 곳에 저장해야합니다.
<시간>자원 :
서블릿의 정적 변수-언제 사용할 수 있습니까?
동일한 주제 :
서블릿과 웹 서비스 사이에 정적 객체 공유하기
- 답변 # 3
정적 변수는 공유됩니다. 정적 변수는 하나의 인스턴스에 속하지 않으며 클래스의 모든 인스턴스에서 액세스 할 수 있습니다. 생성자를 사용하는 경우 생성자에서 하나의 객체 (클래스의 한 인스턴스)를 만드는 데 사용됩니다. 생성자에서 정적 변수를 설정하는 것은 생성하는 객체의 범위를 벗어난 것이기 때문에 일반적으로 의미가 없습니다. .
작동하는 것에 관해서는 HttpSession에 jobId를 넣을 수 있고 각 사용자는 자신의 사본을 가질 수 있습니다.
- 답변 # 4
서블릿의 인스턴스화 정책은 서블릿 스펙에 정의되어 있지 않습니다 ( 내가 기억할 수있는 한, 누구든지)하지만 일반적인 동작은 서블릿 구성 당 하나의 인스턴스 만 만드는 것 같습니다. 따라서 귀하의 경우 모든 요청에 동일한 변수가 사용됩니다.
내가 너라면, jobId를 매개 변수로
Runnable
에 보내는 것을 고려할 것이다 스레드를 실행 중입니다. 예를 들어,이 대신에 :public class HelloWorld extends HttpServlet { private static long jobId; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { jobId = Long.parseLong(request.getParameter("jobid"); new Thread(new Worker()).start(); } static class Worker implements Runnable { @Override public void run() { doSomethingWith(jobId); } } }
다음과 같이 정적 변수를 리팩터링하십시오 :
public class HelloWorld extends HttpServlet { // private static long jobId; -- delete, no longer needed public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { long jobId = Long.parseLong(request.getParameter("jobid"); // local variable new Thread(new Worker(jobId)).start(); // send jobId as parameter } static class Worker implements Runnable { private final long jobId; // non-static; every instance has one public Worker(long jobId) { // allow injection of jobId this.jobId = jobId; } @Override public void run() { doSomethingWith(jobId); // use instance variable instead of static } } }
읽기 쉽고 동시성 문제가 없음-순수한 승리.
관련 자료
- 정적 멤버 변수에 대한 C ++ 핵심 지침
- reference - 변수에 대한 값 모델을 동적 입력이 아닌 정적 입력과 함께 만 사용할 수 있습니까?
- 정적 변수 (C ++)로 이러한 함수를 어떻게 건조시킬 수 있습니까?
- c++ - 파일 시작이 아닌 함수에서 정적 변수 초기화
- C static 키워드가 변수의 헤더 파일에서 사용되거나 사용될 수있는 경우가 있습니까?
- c++ - 정적 및 const 멤버 변수가있는 객체
- c++ - 재 계산 값을 방지하기 위해 함수에 정적 변수를 사용해야합니까?
- data persistence - 파이썬에서 클래스의 정적 변수를 영구적으로 업데이트
- data structures - 가변 가변 Julia 구조체에서 정적 변수가 가능합니까?
- c++ - 함수 내 정적 ifstream 객체의 동작
- javascript - Typescript에서 정적 변수로 생성자 함수를 어떻게 표현할 수 있습니까?
- python - 함수에서 클래스 외부에서 정적 NamedTuples 변수 사용
- c# - 공개 정적 변수에 대한 가장 좋은 대안은 무엇입니까?
- x86 64 - 어셈블리 - 정적/전역 변수의 위치
- java - 정적 변수에 대한 예외
- storage class specifier - C 범위 밖에서 자동 및 정적 변수에 어떻게 액세스 할 수 있습니까?
- python - 파이썬에서 정적 변수는 언제 초기화됩니까?
- c# - 새 객체에서 참조로 정적 값 변수 수정
- c# - 부모-자식 클래스 정적 변수는 변경되지 않습니다
- java.sql.SQLException: 선택된 데이터베이스가 없지만 URL에 있습니다.
- python : 동기 스레드와 비동기 스레드를 구별하는 방법은 무엇입니까?
- java : threadPool과 비교하여 Vert.x의 장점은 무엇입니까?
- JAVA에서 실행기 서비스와 병렬로 동일한 기능을 호출하는 방법은 무엇입니까?
- java : 목록을 사용하여 병렬로 함수를 호출하는 방법은 무엇입니까?
- 디버깅하지 않는 Java 서블릿
- Java 실행기 프레임워크에서 ThreadFactory로 ThreadPoolExecutor 이해하기
- java : 메인 스레드와 종료
- java : 서블릿에서 자바 스크립트 쿠키를 호출하는 방법은 무엇입니까?
- java : 큐를 사용하는 생산자/소비자 스레드
서블릿은 웹 애플리케이션 시작시 한 번만 작성되며 모든 요청간에 공유됩니다. 정적이든 아니든 모든 클래스/인스턴스 변수는 모든 요청/세션간에 공유됩니다. 요청/세션 범위 데이터를 할당하고 싶지 않습니다. 대신 메소드 로컬 변수로 선언/할당하십시오. 예 :
레거시 및더 이상 사용되지 않음
참조 :SingleThreadModel
가 있습니다 모든 요청 중에 서블릿이 강제로 작성하도록 구현할 수있는 인터페이스. 그러나 이것은 나쁜 디자인이며 불필요하게 비쌉니다. 이것이 더 이상 사용되지 않는 이유이기도합니다.서블릿 인스턴스 및 멀티 스레딩
서블릿은 어떻게 작동합니까?