2010-04-30 14 views
5

Bir ScheduledThreadPoolExecutor nesnesini kullanarak bir görev zamanlama yapıyorum. Aşağıdaki yöntemi kullanın:ScheduledThreadPoolExecutor CPU zaman tutarsızlığı nedeniyle yanlış bir zaman yürütme

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

ve 30 saniye (gecikme = 30,000 birim = TimeUnit.MILLISECONDS) gecikme ayarlayın. Bazen görevim hemen gerçekleşir ve diğer zamanlarda 70 saniye sürer.

ScheduledThreadPoolExecutor'ın CPU'ya özel saat kullandığını düşünüyorum. ı [işlemci özgüdür] System.currentTimeMillis(), System.nanoTime() karşılaştırma testleri zaman ı aşağıdaki

zamanlama bakınız: 1272637682667ms

fark 7858386270968425ns: 1272637682651ms,

yürütmek 7858346157228410ns Nasıl bu sorunu çözebilirim 40 saniye

iki işlemci saatler arasında tutarsızlık bulunuyor gibi 16 ms ama 4011374001ns (veya 40,113ms)

yüzden görünüyor i java kodu? Ne yazık ki bu bir müşteri makinesi ve sistemlerini değiştiremiyorum.

+0

Zor olanı. Belki de java.util.Calendar' yardımcı olur? Calendar.getInstance() ve benzeri .. –

+1

Bu kodu bir Virual Machine'de çalıştırıyor musunuz (VMWare, KVM, Virtual PC)? Sanallaştırma, işlemci saati ile milisaniye seviyesinde bile zarar verebilir. –

+0

Doğrudan bir Windows XP Mesleki makinesinde çalışıyor. Sanallaştırma yok. – richs

cevap

2

Evet, ScheduledThreadPoolExecutor'ın System.nanoTime() kullanması doğru. Ayrıca, System.nanoTime() 'ın belirli sistem örneğine bağlı olduğu konusunda da haklısınız. Süreciniz zamanlama ve yürütme arasında geçiş yaparsa, o zaman şansınız kalmaz. (Çok CPU'lu bir sistemde CPU'lar arasında geçiş yapmanın önemli olacağını düşünmüyorum, ama belki de yapıyor? Kesinlikle bir VM'de çalışıyorsanız ve VM'ler ana bilgisayarlar arasında geçiş yapıyorsa önemli olurdu).

Bu durumda tek gerçek çözüm ScheduledThreadPoolExecutor dışında bir şey kullanmak olduğunu düşünüyorum ... Sadece ScheduledThreadPoolExecutor.now() değişiyor gibi basit değil. AbstractQueuedSynchronizer $ ConditionObject.awaitNanos() System.nanoTime() kullanır.

Projelerimden biri iş zamanlaması için Quartz kullanıyor ve bu kitaplıkla tanımladığınız sorunu hiç görmedim. Uygulama ayrıntılarını bilmiyorum (belki de sadece System.nanoTime() kullanır, ama belki de değil?).

İlgili konular