2012-02-23 2 views
5

Java에서 ThreadPoolExecutor을 사용하는 동안 RejectedExecutionException을 처리하는 가장 좋은 방법은 무엇입니까?Java에서 ThreadPoolExecutor로 RejectedExecutionException을 처리하는 방법

제출 된 작업을 간과해서는 안되며 반드시 실행해야합니다. 현재로서는 작업을 완료하기위한 까다로운 실시간 요구 사항이 없습니다.

내가 할 수 있다고 생각했던 것들 중 하나는 실행 가능한 대기열에 공간이 있다는 것을 알기 전까지 루프를 기다리고 나서 대기열에 계속 추가하는 것입니다.

사람들이 경험을 공유 할 수 있다면 기쁘게 생각합니다.

만 동시 스레드의 특정 번호 (일반적으로 좋은 일을) 허용하도록 스레드 풀을 제한 한 경우
while(executor.getQueue().remainingCapacity <= 0){ 
// keep looping 
Thread.sleep(100); 
}; 
//if the loop exits ,indicates that we have space in the queue hence 
//go ahead and add to the queue 
executor.execute(new ThreadInstance(params)); 
+0

두 개 이상의 스레드가이 작업을 시도하면 경쟁 조건이 생성됩니다. 또한 실행 프로그램이 대기열을 지우는 데 오래 걸릴 수도있는 CPU를 구울 것입니다. 예 : 가산기와 집행자를위한 CPU가 하나만있는 경우 이는 심각한 재앙입니다. –

+0

아키텍처에서이 작업을 수행하는 스레드가 하나 뿐이며 CPU 시간을 처리하기 위해 스레드를 수면 상태로 만듭니다. 어떻게 보이나요? – Neeraj

+0

짧은 시간 (심지어 1 - 10ms)조차도 잠자는 것보다 훨씬 좋습니다. 100ms도 좋은 값입니다. 퍼블리싱 스레드가 하나 뿐이라면 괜찮습니다. –

답변

3

대기열의 동작이 변경됩니다. 예 :

public class MyBlockingQueue<E> extends ArrayBlockingQueue<E> { 
    private final long timeoutMS; 

    public MyBlockingQueue(int capacity, long timeoutMS) { 
     super(capacity); 
     this.timeoutMS = timeoutMS; 
    } 

    @Override 
    public boolean offer(E e) { 
     try { 
      return super.offer(e, timeoutMS, TimeUnit.MILLISECONDS); 
     } catch (InterruptedException e1) { 
      Thread.currentThread().interrupt(); 
      return false; 
     } 
    } 
} 

이렇게하면 대기열이 비우기 전에 대기열이 비워 질 때까지 대기합니다.

+0

Cant 난 while (executor.getQueue(). remainingCapacity <= 0) {// 루핑 유지}와 같은 작업을 수행합니다. // 루프가 종료되면 대기열에 공간이 있으므로 // 계속 진행하여 대기열에 추가 함을 나타냅니다. executor.execute (new ThreadInstance (params)); 이것은 ArrayBlockingQueue의 고유 한 인스턴스를 만들지 않고도 해결할 수있는 솔루션입니다. – Neeraj

+0

아픈 내 질문에 코드를 추가합니다. 여기 보이는 것처럼 보입니다. – Neeraj

+1

당신은 경쟁 조건을 가지고 있습니다. 다른 스레드가 동일한 작업을 수행하려고 시도하는 큐를 채울 수 없다는 보장은 없습니다. 자신 만의 ArrayBlockingQueue를 만들 필요는 없습니다. 복사 할 수 있습니다. ;) –

2

은 다음 응용 프로그램이 어떻게 든 푸시에 필요 :

그래도 난의 가능한 솔루션을 추가 호출 코드를 다시 호출하면 ThreadPoolExecutor에서 RejectedExecutionException을 수신하면이를 호출자에게 나타내야하며 호출자이 재 시도를 처리해야합니다.

비슷한 상황은 부하가 많은 웹 서버입니다. 클라이언트가 연결되면 웹 서버는 503 - 서비스를 사용할 수 없음 (일반적으로 임시 조건)을 반환해야하며 클라이언트가 이에 대한 조치를 결정합니다.

관련 문제