2013-01-10 31 views
5

Böyle bir günlük görevi çalıştırmak için ScheduledExecutorService.scheduleAtFixedRate kullanın:Doğruluk/JVM

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

(d milisaniye cinsinden ilk gecikme).

Yürütücü Executors.newSingleThreadScheduledExecutor() tarafından oluşturulur ve birden çok görevi çalıştırır, ancak bunların tümü birkaç saat aralıklarla programlanır ve en fazla birkaç dakika alır.

ScheduledExecutorService'in doğruluğu konusunda hiçbir garanti vermediğini biliyorum ve bunu elde etmek için gerçek zamanlı bir işletim sistemi ve JVM'ye ihtiyacım var. Bu benim görevim için bir zorunluluk değil.

Bir Windows 2003 Server'da, JDK 1.7.0_03 kullanarak, görevin günde yaklaşık 10 saniye kalacağını fark ettim. Bu benim uygulama için kabul edilebilir, ayda yaklaşık 5 dakika yapar. Muhtemelen yeniden programlamayı uygulamak zorunda kalacağım çünkü görevlerin belirli bir yerel saatte çalışmasını istiyorum ve bu yüzden DST'ye kendim dikkat etmeliyim. Servis, uzun süreler boyunca çalışır - yeniden başlamadan yarım yıl, bu olağandışı değildir. Yine de, 10 san/gün'lük bir yanlışlığın çoğunlukla boş bir sistem için oldukça yüksek olduğunu ve daha da kötüye giden davranışlar için hazırlanmam gerekip gerekmediğini düşünüyorum.

Bu yüzden sorum, scheduleAtFixedRate ile olan deneyimleriniz hakkındadır. 10 sn/gün normal mi? Diğer ortamlarda (müşterilerimiz Linux ve Solaris sunucuları kullanıyor) daha iyi veya daha kötü bir doğruluk elde edebilecek miyim? Ya da 10 saniye, çevremizde bir şeyin yanlış olduğunu gösteren bir işaret midir?

+1

Not: '24L * 3600 * 1000, TimeUnit.MILLISECONDS',' 1, TimeUnit.DAYS' ile eşdeğerdir ... Bu, zaman birimlerinin tüm noktasıdır: zaman birimi dönüşümlerinden kaçınmak! – assylias

+1

@assylias evet, ancak initialDelay d milisaniyedir ve yalnızca bir TimeUnit argümanı var. – Chris

+1

Quartz veya Spring 'görev: zamanlanmış görevler'i kullanarak belirli bir yerel saatte tetiklerim, sonra bu sorunla karşılaşmazsınız. – luukes

cevap

2

Çok uzun süren bir görev için çok da şaşırtıcı değil. Diğer bir sorununuz ise NTP veya benzeri ile senkronize olmayan nanoTime() kullanmasıdır. Bu, duvar saati ile sürüklenmeye neden olabilir.

Bundan kaçınmanın bir yolu, önerdiğiniz şekilde art arda programlamaktır. Yinelenen görevler aslında kendileri yeniden programlanırlar (bu yüzden bir istisna alamazlar, aşağıya bakınız) Duvar saati saatini kullanarak ve gün listesi tasarruflarını hesaba katarak, sonunda kendini yeniden planlayan tek bir atış görevine sahip olabilirsiniz.

BTW: Bir istisna veya hatta fırlatılabilir atıldığınızdan emin olursunuz. Eğer göreviniz durmazsa, muhtemelen sessizce (Gelecek nesnesine bakmadıkça, iade edilir)

Yaptığım şey biraz aldatmaktır. Her 10 saniyede bir uyanan bir görevim var ve kaçması gerekip gerekmediğini kontrol etmem gerekiyor. Binlerce göreviniz yoksa ve uygulanması çok daha basitse, genel gider genellikle önemsizdir.