Java Timer vs ExecutorService?


263

Ben kullanarak bir görev zamanlama kodu var java.util.Timer. Etrafa bakıyordum ve ExecutorServiceaynı şeyi yapabileceğini gördüm . Buradaki soru, kullandınız mı Timerve ExecutorServicegörevleri zamanlamak için, birinin diğerine göre faydası nedir?

Ayrıca, herhangi birinin Timersınıfı kullanıp kullanmadığını ve ExecutorServiceonlar için çözülen herhangi bir sorunla karşılaşıp karşılaşmadığını kontrol etmek istedim .


1
Hatta daha featurefull şeye ihtiyacın olursa, kontrol kuvars . Cron gibi zamanlama, kümeye duyarlı zamanlama, işler üzerinde bireysel kontrol (bir seferde bir çalışma, bağımlılıklar vb. Gibi) dahil olmak üzere çok daha fazla iş kontrolü sağlar. --Zaman
Tim

Yanıtlar:


313

Uygulamada Java Eşzamanlılığına göre :

  • Timersistem saatindeki değişikliklere duyarlı olabilir ScheduledThreadPoolExecutor, değil.
  • Timeryalnızca bir yürütme iş parçacığına sahiptir, bu nedenle uzun süren görev diğer görevleri geciktirebilir. ScheduledThreadPoolExecutorherhangi bir sayıda iş parçacığı ile yapılandırılabilir. Ayrıca, isterseniz (sağlayarak ThreadFactory) , oluşturulan iş parçacıkları üzerinde tam denetime sahip olursunuz .
  • Çalışma zamanı istisnaları TimerTaskbir iş parçacığını öldürür, böylece Timerölü olur :-( ... yani zamanlanmış görevler artık çalışmaz. ScheduledThreadExecutorSadece çalışma zamanı istisnalarını yakalamaz, aynı zamanda bunları (işlem afterExecuteyöntemini geçersiz kılarak ThreadPoolExecutor) ele almanızı sağlar . istisna attı iptal edilecek, ancak diğer görevler çalışmaya devam edecektir.

ScheduledThreadExecutorBunun yerine kullanabilirsiniz Timer.

Bir şey daha var ... ScheduledThreadExecutorJava 1.4 kütüphanesinde mevcut olmasa da, sınıfı olan Java 1.2, 1.3, 1.4 için bir JSR 166 ( java.util.concurrent) Backport var ScheduledThreadExecutor.


63

Size sunulmuşsa ise, o zaman bir sebep geliyor zor değil Java 5 infaz çerçevesini kullanmak. Arayan:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();

size ScheduledExecutorServicebenzer bir işleve sahip olacak Timer(yani tek iş parçacıklı olacak) ancak erişimi biraz daha ölçeklenebilir olabilir (kaputun altında, Timersınıfla olduğu gibi tam senkronizasyon yerine eşzamanlı yapılar kullanır ). A kullanmak ScheduledExecutorServiceayrıca size avantajlar sağlar:

  • Gerekirse özelleştirebilirsiniz ( newScheduledThreadPoolExecutor()veya ScheduledThreadPoolExecutorsınıfa bakın)
  • 'Bir defalık' yürütmeler sonuç döndürebilir

TimerAklıma gelmenin tek nedeni hakkında :

  • Java 5 öncesi mevcuttur
  • J2ME'de benzer bir sınıf sağlanmıştır, bu da uygulamanızı taşımayı kolaylaştırabilir (ancak bu durumda ortak bir soyutlama katmanı eklemek çok zor olmaz)

1
Kullanmanın bir başka nedeni, eşdeğeri gibi görünmeyen yöntemin kullanılabilirliği TimerTaskolabilir . scheduledExecutionTime()ScheduledExecutorService
Rohit Agarwal

3
Başka bir not: Bu yorumu 2k17'de yazıyorum, artık J2ME yok. zaten öldü.
msangel

1
Java Timer sınıfı berbat.
JohnyTex

26

ExecutorService daha yeni ve daha geneldir. Zamanlayıcı, yalnızca planladığınız şeyleri düzenli olarak çalıştıran bir iş parçacığıdır.

ExecutorService bir iş parçacığı havuzu olabilir, hatta bir kümedeki diğer sistemlere yayılmış olabilir ve tek seferlik toplu yürütme vb.

Her birinin karar vermeyi önerdiğine bakın.



8

ScheduledThreadPoolExecutor üzerindeki Oracle belgeleri sayfasından

Bir ThreadPoolExecutor ilave programlanacağını Verili bir gecikmeden sonra çalıştırmak için, ya da düzenli olarak çalıştırmak. Bu sınıf, birden çok çalışan iş parçacığı gerektiğinde veya ThreadPoolExecutor'un (bu sınıfın genişlettiği) ek esnekliği veya özellikleri gerektiğinde Zamanlayıcıya tercih edilir .

ExecutorService/ThreadPoolExecutorveya ScheduledThreadPoolExecutorbirden çok çalışan iş parçacığınız olduğunda bariz bir seçimdir.

ExecutorServiceOver ArtılarıTimer

  1. TimerForkJoinPool gibi ExecutorServicelezzetleri kullanan birden fazla görevden farklı olarak mevcut CPU çekirdeklerinden yararlanamaz ExecutorService
  2. ExecutorServicebirden fazla görev arasında koordinasyona ihtiyacınız varsa işbirlikçi API sağlar. N sayıda işçi görevi göndermeniz ve bunların tamamlanmasını beklemeniz gerektiğini varsayın. İnvokeAll API ile kolayca başarabilirsiniz . Aynı şeyi birden fazla Timergörevle başarmak istiyorsanız , bu kolay olmayacaktır.
  3. ThreadPoolExecutor İş Parçacığı yaşam döngüsünün yönetimi için daha iyi API sağlar.

    İş parçacığı havuzları iki farklı soruna yöneliktir: genellikle görev başına çağırma yükünün azalması nedeniyle çok sayıda eşzamansız görev yürütürken gelişmiş performans sağlarlar ve görevler. Her ThreadPoolExecutor tamamlanmış görev sayısı gibi bazı temel istatistikleri de korur

    Birkaç avantaj:

    a. Konuların yaşam döngüsünü oluşturabilir / yönetebilir / kontrol edebilir ve iplik oluşturma maliyeti ek yüklerini optimize edebilirsiniz

    b. Görevlerin işlenmesini (İş Çalma, ForkJoinPool, invokeAll) vb. Kontrol edebilirsiniz.

    c. İş parçacıklarının ilerlemesini ve sağlığını izleyebilirsiniz

    d. Daha iyi istisna yönetim mekanizması sağlar


5

Bazen Timer'ı Execrators.newSingleThreadScheduledExecutor () üzerinde tercih etme nedenim, zamanlayıcı daemon iş parçacıkları üzerinde yürütmek için zamanlayıcı gerektiğinde çok daha temiz kod almak olmasıdır.

karşılaştırmak

private final ThreadFactory threadFactory = new ThreadFactory() {
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
};
private final ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(threadFactory); 

ile

private final Timer timer = new Timer(true);

Bunu bir yöneticinin sağlamlığına ihtiyaç duymadığım zamanlarda yaparım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.