Mam kod, za pomocą którego planuję zadanie java.util.Timer
. Rozejrzałem się i zobaczyłem, że ExecutorService
mogę zrobić to samo. To pytanie tutaj, czy używałeś Timer
i ExecutorService
planowałeś zadania, jaka jest korzyść z jednego korzystania z drugiego?
Chciałem również sprawdzić, czy ktoś skorzystał z Timer
klasy i napotkał problemy, które ExecutorService
dla nich rozwiązały.
Odpowiedzi:
Według Java Concurrency in Practice :
Timer
może być wrażliwy na zmiany w zegarze systemowym,ScheduledThreadPoolExecutor
prawda.Timer
ma tylko jeden wątek wykonania, więc długotrwałe zadanie może opóźnić inne zadania.ScheduledThreadPoolExecutor
można skonfigurować z dowolną liczbą wątków. Ponadto masz pełną kontrolę nad tworzonymi wątkami, jeśli chcesz (pod warunkiemThreadFactory
).TimerTask
zabijają ten jeden wątek, powodując w ten sposóbTimer
utratę :-( ... tj. Zaplanowane zadania nie będą już działać.ScheduledThreadExecutor
Nie tylko wychwytują wyjątki środowiska wykonawczego, ale także pozwalają je obsłużyć, jeśli chcesz (zastępującafterExecute
metodę zThreadPoolExecutor
). Zadanie, które zgłoszony wyjątek zostanie anulowany, ale inne zadania będą nadal działać.Jeśli możesz użyć
ScheduledThreadExecutor
zamiastTimer
, zrób to.Jeszcze jedna rzecz ... chociaż
ScheduledThreadExecutor
nie jest dostępna w bibliotece Java 1.4, istnieje Backport JSR 166 (java.util.concurrent
) do Java 1.2, 1.3, 1.4 , który maScheduledThreadExecutor
klasę.źródło
Jeśli jest on dostępny, trudno jest wymyślić powód, aby nie używać frameworka Java 5. Powołanie:
da ci
ScheduledExecutorService
podobną funkcjonalność doTimer
(tj. będzie jednowątkowy), ale do którego dostęp może być nieco bardziej skalowalny (pod maską używa współbieżnych struktur zamiast pełnej synchronizacji jak w przypadkuTimer
klasy). Użycie aScheduledExecutorService
daje również takie korzyści, jak:newScheduledThreadPoolExecutor()
lubScheduledThreadPoolExecutor
)Jedyne powody, dla
Timer
których mogę się trzymać , to:źródło
TimerTask
może być dostępnośćscheduledExecutionTime()
metody, która nie wydaje się mieć odpowiednika wScheduledExecutorService
.ExecutorService jest nowszy i bardziej ogólny. Timer to tylko wątek, który okresowo uruchamia zaplanowane dla niego rzeczy.
Usługa ExecutorService może być pulą wątków lub nawet rozproszona na inne systemy w klastrze i wykonywać takie czynności, jak jednorazowe wykonywanie wsadowe itp.
Wystarczy spojrzeć na to, co każda oferta decyduje.
źródło
Oto kilka dobrych praktyk dotyczących korzystania z timera:
http://tech.puredanger.com/2008/09/22/timer-rules/
Ogólnie rzecz biorąc, używałbym Timera do szybkich i brudnych rzeczy, a Executora do bardziej niezawodnego użytkowania.
źródło
Ze strony dokumentacji Oracle na ScheduledThreadPoolExecutor
ExecutorService/ThreadPoolExecutor
lubScheduledThreadPoolExecutor
jest oczywistym wyborem, jeśli masz wiele wątków roboczych.Zalety
ExecutorService
ponadTimer
Timer
nie może korzystać z dostępnych rdzeni procesora, w przeciwieństwieExecutorService
do wielu zadań z wykorzystaniem smakówExecutorService
takich jak ForkJoinPoolExecutorService
zapewnia wspólny interfejs API, jeśli potrzebujesz koordynacji między wieloma zadaniami. Załóżmy, że musisz przesłać N liczby zadań roboczych i poczekać na ich zakończenie. Możesz to łatwo osiągnąć dzięki invokeAll API. Jeśli chcesz osiągnąć to samo z wielomaTimer
zadaniami, nie byłoby to proste.ThreadPoolExecutor zapewnia lepszy interfejs API do zarządzania cyklem życia wątku.
Kilka zalet:
za. Możesz tworzyć / zarządzać / kontrolować cykl życia wątków i optymalizować koszty tworzenia wątków
b. Możesz kontrolować przetwarzanie zadań (kradzież pracy, ForkJoinPool, invokeAll) itp.
do. Możesz monitorować postęp i zdrowie wątków
re. Zapewnia lepszy mechanizm obsługi wyjątków
źródło
Moim powodem, dla którego czasami wolę Timer niż Executors.newSingleThreadScheduledExecutor (), jest to, że otrzymuję znacznie czystszy kod, gdy potrzebuję timera do wykonania na wątkach demona.
porównać
z
Robię to, gdy nie potrzebuję solidności usługi wykonawczej.
źródło