2010-04-30 3 views
5

ScheduledThreadPoolExecutor 개체를 사용하여 작업을 예약하고 있습니다. I는 이하의 방법에 사용CPU 시간 차이로 인해 ScheduledThreadPoolExecutor에서 잘못된 시간이 실행됩니다.

public ScheduledFuture<?> schedule(Runnable command, long delay,TimeUnit unit) 

을 30 초 (지연 = 30,000 단위 = TimeUnit.MILLISECONDS)의 지연을 설정. 때로는 작업이 즉시 발생하고 다른 작업에는 70 초가 걸리기도합니다.

저는 ScheduledThreadPoolExecutor가 CPU 특정 클럭을 사용한다고 생각합니다. 난 [CPU 특정]에 System.currentTimeMillis() System.nanoTime()를 비교 테스트를 실행하면 난 다음

일정 참조 : 1272637682667ms

차이가 7858386270968425ns : 1272637682651ms,

실행 7858346157228410ns 어떻게이 문제를 해결 할 40초

두 개의 CPU 클럭 사이의 불일치가 같은 16ms하지만 4011374001ns (또는 40,113ms)

은 그래서 보이는 난 n 자바 코드? 불행히도 이것은 클라이언트 컴퓨터이며 시스템을 수정할 수 없습니다.

+0

까다로운 것. 아마'java.util.Calendar'가 도움이 될까요? Calendar.getInstance() 등 –

+1

Virual Machine (VMWare, KVM, Virtual PC)에서이 코드를 실행하고 있습니까? 가상화는 밀리 초 수준의 CPU 클럭으로 인해 혼란을 야기 할 수 있습니다. –

+0

Windows XP Professional 컴퓨터에서 직접 실행됩니다. 가상화가 필요 없습니다. – richs

답변

2

예, ScheduledThreadPoolExecutor가 System.nanoTime()을 사용하는 것이 맞습니다. 그리고 System.nanoTime()이 특정 시스템 인스턴스에 종속되어 있다는 것도 맞습니다. 프로세스가 일정과 실행 사이에서 마이그레이션되면 운이 없어진 것입니다. (다중 CPU 시스템의 CPU 간 마이그레이션은 중요하지 않겠지 만 어쩌면 그렇게 할 수 있을까요? VM에서 실행 중이고 VM이 호스트간에 마이그레이션 한 경우 문제가 될 수 있습니다).

이 경우 유일한 해결책은 ScheduledThreadPoolExecutor가 아닌 다른 것을 사용하는 것입니다 ... ScheduledThreadPoolExecutor.now()를 변경하는 것만 큼 단순하지는 않습니다. AbstractQueuedSynchronizer $ ConditionObject.awaitNanos()도 System.nanoTime()을 사용합니다.

내 프로젝트 중 하나는 작업 스케줄링에 Quartz을 사용하며이 라이브러리에서 설명하는 문제를 본 적이 없습니다. 구현 세부 사항을 모르겠다. (아마 System.nanoTime()도 사용하지만 어쩌면 그렇지 않은 것일까?).

관련 문제