2011-02-17 4 views
2

난 그냥 내 실행 가능한의 run() 방법이 코드를 작성 : 당신이 볼 수 있듯이 작업은 DB 연결을 얻을 수없는 경우문제가 발생해도 재 시행을 원한다면 동일한 Executor로 Runnable을 re-enqueue하는 것이 안전합니까?

try { 
    dbConnection = MyApp.datasource.getConnection(); 
} catch (SQLException e) { 
    logger.log(Level.SEVERE, "Could not obtain a DB connection! Re-enqueuing this task. Message: " + e.getMessage(), e); 
    MyApp.executor.execute(this); 
    return; 
} 

것은, 그것이 있었다 같은 큐에 자체-대기열을 다시한다 그것이 달리기 전에.

나는 이것이 라고 생각하고 있습니다.은 안전하지만 재밌는 느낌이 들며, 제가 놓친 부분이 없도록하고 싶습니다.

감사합니다.

+2

re-enqueuing 전에'Thread.sleep()'를 추가하고 싶을 수도 있습니다. 그렇지 않으면 getConnection()이 빨리 실패하면 많은 CPU로드 (및 로깅으로 인해 아마도 I/O로드)가 생성됩니다. –

답변

5

집행자가가는 한 괜찮습니다.

그러나 오류가 매우 빠르게 발생할 수 있으므로 실행 프로그램이 코드를 신속하게 다시 실행할 수 있습니다. 결과가 나오지 않을 경우 많은 CPU를 태울 수 있습니다.

강제 재시도 지연 및 최대 루프 카운트가 빌드됩니다.

4
  1. 가 발생하는 소위 포이즌 메시지의 위험이 있습니다 다음 SQLException 도망하지 않을 경우 작업이 무한 그 자체를 반복합니다. 어떤 종류의 카운터 나 타이머를 제공해야합니다.

  2. 실행 프로그램의 점유율 (이미 예약 된 동시 작업 수)에 따라 재 시도 간의 간격이 크게 다를 수 있습니다. CPU의 100 %를 사용하거나 매우 오랜 시간 동안 재 시도를 기다릴 수 있습니다. , 사고에 의해, 당신의 부모 작업 (자체-일정을 다시 한)이 아이의 결과를 기다리는 경우 실행 프로그램에서만 실행될 때

  3. 는 (다시 예정) 호출, 당신은 교착 상태가 발생할 수 있습니다 하나의 스레드.

  4. MyApp의 원시 필드를 사용하는 경우 잘못된 패턴 인 것 같습니다.

전반적인 개념은 다음과 같습니다. run()에 루프가없는 이유는 무엇입니까? 당신은 실행되고있는 다른 업무에보다 공정하고 싶습니까?

관련 문제