Перевага ScheduledExecutorService
надTimer
Я хочу запропонувати вам альтернативу Timer
використанню - ScheduledThreadPoolExecutor , реалізація інтерфейсу ScheduledExecutorService . Він має деякі переваги перед класом Timer, згідно з "Java у паралельності":
A Timer
створює лише один потік для виконання завдань таймера. Якщо завдання таймера триває надто довго, точність синхронізації інших
TimerTask
може постраждати. Якщо повторне TimerTask
планується запустити кожні 10 мс, а інше завдання таймера займає 40 мс, повторюване завдання (залежно від того, чи було воно заплановане із фіксованою швидкістю або фіксованою затримкою) викликається чотири рази швидко після послідовного запущене завдання завершує або повністю «пропускає» чотири виклики. Планові пули потоків вирішують це обмеження, дозволяючи надавати декілька потоків для виконання відкладених та періодичних завдань.
Інша проблема таймера полягає в тому, що він поводиться погано, якщо TimerTask
видає неперевірений виняток . Також називається "витік нитки"
Потік таймера не вловлює виняток, тому неперевірений виняток, викинутий із TimerTask
терміна, завершує потік таймера. Таймер також не відроджує нитку в цій ситуації; натомість помилково вважається, що весь таймер було скасовано. У цьому випадку тимчасові завдання, які вже заплановані, але ще не виконуються, ніколи не запускаються, і нові завдання не можна запланувати.
І ще одна рекомендація , якщо ви хочете створити свій власний сервіс планування, ви все одно можете бути в змозі скористатися перевагами бібліотеки, використовуючи DelayQueue
, в BlockingQueue
реалізацію , яка забезпечує функціональні можливості диспетчеризації ScheduledThreadPoolExecutor
. A DelayQueue
управляє колекцією об'єктів із затримкою. Затримка пов’язана з часом затримки: DelayQueue
дозволяє взяти елемент, лише якщо його затримка минула. Об'єкти повертаються із DelayQueue
замовленого до часу, пов'язаного з їх затримкою.