2011-03-28 3 views
0

외부 서비스를 호출하는 서블릿에서 코드를 호출했습니다. 물론 응답을 반환하는 데 서비스가 얼마나 오래 걸릴지 보장하지 않습니다. 이 서비스에 대한 호출이 한 번에 하나만 실행되도록해야하지만 서블릿 컨테이너는 서블릿에 대한 동시 요청을 실행할 수 있습니다. 먼저 서버의 첫 번째 서버에서 요청의 우선 순위가 단일 파일로 처리되도록 보장하고자합니다. 따라서 일단 외부 호출이 끝나면 다음 호출을하기 위해 어떤 스레드가 들어 왔는지 보장 할 수 없기 때문에 외부 서블릿 호출이 동기화되는 것만으로는 충분하지 않습니다.보증 스레드 실행 순서가 먼저옵니다.

아이디어가 있으십니까?

+0

입니다 어쨌든 어느 것이 먼저 왔는지 당신은 정말로 알지 못합니다. 나는 요청의 순서에 관해서는별로 걱정하지 않을 것이며, 단지 그들이 서로 상호 작용하는 것으로부터 고립되어 있다는 것이다. – corsiKa

+0

첫 번째 요청을 처리하는 데 20 분이 소요됩니다. 20 분 전에 올 수 있었던 1에서 n-1 전에 1 초 전에 실행 된 n 번째 요청을 처리하는 것이 공평합니까? 이런 식으로 완전한 기아를 가질 수 있습니다. (그렇다면 20 분이 극단적이며 관련이있는 다른 이슈를 제기 할 것입니다) – harschware

+0

또한 당신은 옳습니다. 그러나 컨테이너의 요청과 달리이 잠재적으로 장기간 실행되는 리소스에 대한 액세스를 제어함으로써 문제의 정도를 완화 할 수 있습니다 잠재적으로 오래 실행되지 않습니다 (내 응용 프로그램은 컨테이너에서 유일한 것입니다). – harschware

답변

4

당신은 공정한 잠금

Lock lock = new ReentrantLock(true); 

이 그것을 시도 된 순서대로 잠금을 제공을 사용할 수 있습니다.

+0

은 Java Concurrency in Practice의 제 13 장을 참조하십시오 (Bloch 외. – harschware

+0

thats는 좋은 ans @peter이었다. 그러나 나는 기다리는 단계 후에 lock 작업에 공평하다고 생각한다. 기다리는 단계에서 더 많은 시간을 가진 스레드가 먼저 활성화된다는 것을 의미한다. – aditya

+0

@Anita 공정한 잠금은 오버 헤드가 많고 느립니다. 이것이 기본 동작이 아닌 이유입니다. 즉, 실제로 필요한 경우에만 사용합니다. –

0

서블릿에 작업자 스레드를 만들고 거기에 콜 아웃을 대기열에 넣습니다. 요청 처리는 대기열에 요청을 추가 할 때 동기화되고 작업자 스레드가 다시보고 할 때까지 대기합니다.

4

당신은 single-threaded ExecutorServiceCallablesubmit에들 (실제 요청을 수행 할) 사용 become availableFuture 값을 기다릴 수 있습니다. java.util.concurrent의

+0

동의합니다. 그러나이 미리 구성된 ExecutorService가 OP의 요구 사항을 훨씬 뛰어 넘는 것으로 강조하고 싶습니다. 설명서에는 작업이 순차적으로 실행된다는 내용이 명시되어 있습니다. http://download.oracle.com/javase/1.5.0 /docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor() – akappa

1

많은 유틸리티가이 상황에 적합, 공정성 설정으로 Semaphore 그래서, 당신이 요청이 서버에 도착하는 소요 시간을 제어 할 수없는 또 다른 선택

import java.util.concurrent.*; 
Semaphore sem = new Semaphore (int n = HOW_MANY_PERMITS, boolean fairness = true);