2009-10-06 4 views
3

동일한 리소스 (파일 또는 ACID가 아닌 MongoDB와 같은 데이터베이스)와 경쟁하기 위해 발생하는 Tomcat Servlet 인스턴스를 동기화하는 권장 방법이 있습니까?Tomcat에서 서블릿 동시성/동기화?

저는 두 개의 Java 스레드가 동시에 같은 Java 객체에 액세스하지 못하도록하기 위해 스레드 동기화에 익숙하지만 JRE 외부에 존재하는 객체는 확인하지 않습니다.

편집 : 1 개의 Tomcat 서버 만 실행 중입니다. 그것이 다른 JVM을 의미하든 그렇지 않든간에, 나는 확신하지 못한다 (나는 그것이 같은 JVM이지만 잠재적으로 다른 쓰레드라고 가정한다).


편집 : 특정 유스 케이스 (그러나 나는 일반적으로 질문 부탁 해요) : 디렉토리에 원시 파일을 넣고, 파일 저장소로

Tomcat 서버 역할을하고 MongoDB를을 사용하여 스토어 메타 데이터. 이것은 동시성 문제를 제외하고는 매우 간단한 개념입니다. 같은 파일을 저장하는 두 개의 동시 요청이 있거나 동일한 개체의 메타 데이터를 동시에 관리하는 경우이를 해결할 방법이 필요하며 어떻게해야할지 모르겠습니다. 가장 쉬운 방법은 요청을 어떻게 든 직렬화/대기열로 만드는 것이라고 생각합니다. Tomcat에서 대기열을 구현하는 방법이 있습니까?

+0

모두 동일한 JVM에서 실행 중이거나 다른 톰캣 인스턴스 내에서 실행되고 있습니까? –

답변

1

외부 리소스가 어떤 이유로 든 Java 객체 (예 : java.io.File)로 표시 될 것입니다. 필요한 경우 언제든지 해당 객체에서 동기화 할 수 있습니다.

물론,이 객체는 서블릿 인스턴스에서 공유되어야한다는 것을 의미합니다.

+1

그리고 이것은 경쟁 리소스를 나타내는 프록시 개체 생성을 제어하는 ​​내부 소프트웨어가 있음을 의미합니다. 오늘날에는 모든 파일이 동일한 파일을 나타내는 자체 File 객체를 만드는 것에서 여러 개의 코드 조각을 막을 수있는 방법이 없습니다. 그래서 당신은 경쟁 자원 당 단 하나의 객체 만 존재하도록하는 일종의 싱글 톤 (singleton) 팩토리를 가져야 할 것입니다. –

+0

@ ChssPly76 : 아니오 아니오 (John이 말한 것) -이 코드를 실행하면 {File f1 = new File ("/ usr/bin"); 파일 f2 = 새 파일 ("/ usr/bin"); System.out.println (f1 == f2); } 당신은 거짓을 얻고, 따라서 한 파일에서 동기화는 다른 파일에서 잠금을 얻을 수 있는지 여부에 영향을주지 않습니다. –

+0

@ Jason - "객체가 공유되어야하는 부분"은 File의 사본 두 개를 만드는 것이 괜찮음을 의미합니까? – ChssPly76

3

일반적으로 다양한 서블릿이 동일한 JVM에서 실행되며, 그렇지 않은 경우 서블릿 러너를 구성 할 수 있어야합니다. 따라서 중앙 집중식 공유 리소스 관리자를 볼 수 있도록 준비 할 수 있습니다.

실제 gubbinry의 경우 평범한 이전 동기화가 적절하지 않은 경우 Semaphore 클래스에서 예제를 찾아보십시오 (링크는 튜토리얼/예를 들어 도움이되기 전에 잠시 썼습니다). 리소스의 "풀"을 처리합니다.

+0

"공유 리소스 관리자를 볼 수 있도록 정렬 할 수 있습니다."- 어떤 종류의 싱글 톤을 만들어야한다는 의미입니까? –

+0

예, 정확하게 - 임의의 서블릿에서 호출하는 정적 메소드 getDatabasePool(), getCacheManager() 등을 사용하여 싱글 톤 클래스를 생성하십시오. –

+0

그런 종류의 병목 현상을 추가하려면 Tomcats SingleThreadedServlet (또는 전략) – Gandalf

1

IMO 문제가 있습니다. 데이터베이스 및 공유 파일 시스템과 같은 것들이 발명 된 이유가 있습니다. 싱글 톤 클래스 나 세마포어를 사용하여 직접 작성하려고하면 실수가 빨리 생길 것입니다. 이를 위해 스토리지 솔루션을 찾아 내면 많은 어려움을 겪지 않게됩니다.

+1

나는 내 자신을 쓰려고하지 않고, 별도의, 잠재적으로 동시적인 Tomcat 요청을 파일이나 MongoDB에 올바르게 쓰는 것이 좋습니다. –

+0

그리고 내 대답은 - 그것은 권장하지 않습니다. – Gandalf

3

하나의 Tomcat 서버를 실행하고 모든 서블릿이 하나의 컨텍스트에있는 경우 해당 컨텍스트 클래스 로더에있는 Java 개체를 항상 동기화 할 수 있습니다. 여러 컨텍스트를 실행중인 경우 "동기화 개체"는 특정 컨텍스트에 상주 할 수 없지만 모든 컨텍스트에서 공유되는 상위 수준에 있어야합니다. "common"클래스 로더를 tomcat 6.0 문서 here에서 사용하여 "동기화 객체"를 배치하면 모든 컨텍스트간에 공유됩니다.

2

2 가지 경우가 있습니다. 동일한 JVM 내에서 파일을 편집하기위한 공통 리소스에 액세스하려는 경우 Java 기능에서 "동기화 됨"을 사용할 수 있습니다. 서로 다른 JVM과 다른 자바 스레드가 공용 리소스에 액세스하는 경우 수동 파일 잠금 코드를 사용하여 큐의 각 스레드 우선 순위 번호를 부여 할 수 있습니다.

관련 문제