2013-01-10 3 views
5

나는 다음과 같이 매일 작업을 실행하는 데 ScheduledExecutorService.scheduleAtFixedRate를 사용정확도/JVM

executor.scheduleAtFixedRate(task, d, 24L * 3600 * 1000, TimeUnit.MILLISECONDS); 

(d는 밀리 초 초기 지연)입니다.

실행자는 Executors.newSingleThreadScheduledExecutor()으로 생성되며 여러 작업을 실행하지만 모두 몇 시간 간격으로 예약되며 최대 몇 분이 소요됩니다.

나는 ScheduledExecutorService가 정확성에 대한 보장을하지 못한다는 것을 안다. 나는 그것을 얻기 위해 실시간 OS와 JVM이 필요하다. 그래도 그건 내 작업에 대한 요구 사항은 아닙니다.

Windows 2003 Server에서 JDK 1.7.0_03을 사용하면 작업이 하루에 거의 10 초씩 발생한다는 것을 알았습니다. 한 달에 약 5 분이 걸리는데, 이는 제 신청에 받아 들일 수 있습니다. 어쨌든 다시 스케쥴링을 구현해야 할 것입니다. 태스크를 특정 로컬 시간에 실행해야하기 때문에 DST를 직접 처리해야하기 때문입니다. 이 서비스는 오랜 기간 동안 실행됩니다. 다시 시작하지 않아도 반년은 그다지 특이하지 않습니다.

여전히 유휴 상태 시스템의 경우 10 초/일의 부정확도가 높다고 생각합니다. 더 나쁜 동작을 대비해야하는지 궁금합니다.

제 질문은 scheduleAtFixedRate의 경험에 대한 것입니다. 10 초/일이 정상입니까? 다른 환경 (고객도 Linux 및 Solaris 서버 사용)에서 정확도가 더 좋거나 나 빠지게됩니까? 아니면 우리 환경에서 무언가가 잘못되었다는 표시가 10 초입니까?

+1

참고 : '24L * 3600 * 1000, TimeUnit.MILLISECONDS'는'1, TimeUnit.DAYS'와 같습니다. 시간 단위 변환을 피하는 것이 전체 시간대입니다. – assylias

+1

@assylias 예. 그러나 initialDelay d는 밀리 초 단위이며 하나의 TimeUnit 인수 만 있습니다. – Chris

+1

Quartz 또는 Spring'task : scheduled-tasks'를 사용하여 특정 로컬 시간에 트리거 할 것이므로이 문제가 없습니다. – luukes

답변

2

매우 오랫동안 실행되는 작업의 경우 너무 놀라운 것은 아닙니다. 또 다른 문제는 NTP와 동기화되지 않은 nanoTime()을 사용한다는 것입니다. 이로 인해 벽시계가 흔들릴 수 있습니다.

이 문제를 피하는 한 가지 방법은 제안대로 반복 일정을 잡는 것입니다. 반복 작업은 실제로 스스로 일정을 재조정합니다 (예외를 throw 할 수없는 이유는 아래 참조). 벽 시계 시간을 사용하고 요일 목록 저장을 고려하여 마지막 일정을 재조정하는 원 샷 작업을 가질 수 있습니다.

동의어 : 나는 예외를 잡거나 Throwable Throwable을 잡을 것입니다. 당신이하지 않으면 당신의 작업은 멈출 것입니다, 아마도 조용히 (당신이 미래의 객체를보고있는 경우를 제외하고)

내가하는 일은 조금 치프입니다. 나는 매 1 ~ 10 초마다 깨어나 실행해야하는지, 돌아 오지 않는지 확인하는 작업을합니다. 수천 개의 작업이없고 구현하기가 훨씬 간단하다면 오버 헤드는 보통 사소한 것입니다.