В разработке нам часто нужны некоторые периодические операции, такие как выполнение определенной операции каждые несколько минут. В настоящее время нам нужно установить таймер. Наиболее удобный и эффективный способ реализации его в Java - это использовать класс инструментов java.util.timer, а затем запланировать задачу java.util.timertask.
Таймер - это инструмент, который использует его для распоряжения задач, которые будут выполняться в фоновых потоках позже. Задачи могут быть выполнены один раз, или они могут быть выполнены неоднократно. На самом деле это поток, который планирует Timertasks, принадлежащие временным планированию.
Timertask - это абстрактный класс, подклассы которых расположены таймером как задачи, которые выполняются или повторяются. На самом деле, это класс с методом выполнения, и код, который необходимо регулярно выполнять, помещается в тело метода прогона.
Java запустила таймер класса Timer в JDK1.3, а затем Doulea недавно разработал PradeLeThreadPoolexeCutor, который поддерживает многопоточное после JDK1.5. Судя по выступлению последнего, мы можем рассмотреть полную замену таймера.
Сравнение между таймером и ScheduleThreadPoolexeCutor:
1. Таймер начинается с JDK1.3. Его принцип - использовать массив Timertask в качестве очереди, чтобы добавить все задачи по времени в эту очередь. Затем запустите ветку. Когда очередь пуст, поток будет блокировать. Когда есть данные в очереди, поток удалит Timertask, чтобы судить
Независимо от того, обновлена ли время, задача начинает работать, если время выполнения меньше или равно текущему времени. Благодаря своему природу единственного потока, он приносит несколько проблем (подробный код уже позже):
Во-первых, когда задачи, которые мы добавляем к таймеру, требуют много времени, поскольку этот таймер выполняет задачи таймера одним последовательным способом, он повлияет на своевременное выполнение последующих задач.
Код Java
// Пример проблемы: m_timer.scheduleatfixedrate (new Taskuselongtime (), 1000, 5000); m_timer.scheduleatfixedrate (new TaskNormal (), 5000, 3000); Запуск 14:44:49: Задача Нормальная выполненная 14:44:49: Таймер спит 10 секунд Анализ результатов: задача TaskNormal не может быть гарантированно запускаться один раз каждые 3 секунды, он может только ждать, пока TaskUselongtime будет запущен после его завершения.
Во -вторых, поток в таймере только поймает исключение прерванного перерыва, поэтому, если наша пользовательская задача времени не затрагивает возможных исключений и не приведет к брошению исключения,
// Пример 2: m_timer.schedule (New TaskThrowException (), 1000); m_timer.schedule (new TaskNormal (), 2000); Результат запуска: 14:47:37: Исключение бросить исключение в ветку «таймер-0» java.lang.runtimeexception на timer_test.timertest $ taskthrowexception.run (timertest.java:85) на java.util.timerthread.mainloo java.util.timerthread.run (Timer.java:462) Анализ результатов: после того, как исключение будет выполнено задачей, последующая задача, препарата для работы не может продолжать работать.
Это приведет к прекращению нашего потока таймера, так что другие последующие задачи не могут быть выполнены.
В -третьих, он не может выполнять несколько задач по времени, которые возникают одновременно
// анализ трех вопросов: m_timer.scheduleatfixedrate (new Taskuselongtime ("timer1"), 1000, 15000); m_timer.scheduleatfixedrate (новый TaskUselongtime ("timer2"), 1000, 15000); Результат работы: 14:50:16: Timer1 спит 10 секунд 14:50:26: Timer2 спит 10 секунд 14:50:36: Timer2 - это 10 секунд.Пример кода:
package timer_test;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TimerTest {private final Timer m_timer = new Timer();public static void main(String[] args) {new TimerTest().test();}public void test() {//A sample проблемы: m_timer.scheduleatfixedrate (new TaskUselongtime (), 1000, 5000); m_timer.scheduleatfixedrate (new TaskNormal (), 5000, 3000); // Пример 2: // m_timer.schedule (new TaskThrowException (), 1000); // m_timer.schedule (new TaskNormal (), 2000); // Пример 3: // m_timer.scheduleatfixedrate (new Taskuselongtime ("timer1"), 1000, 5000); // m_timer.scheduleatfixedrate (new TaskUselongtime ("timer2"), 1000, 5000);} частный класс TaskUselongtime extends timertask {private String m_taskname = "timer"; public taskUselongtime () {} public taskUselongtime (string taskname) {m_taskname = askname at atemase at ateadame =} staskname =} staskname =} staskname; {try {System.out.println (getCurrentTime ()+":"+m_taskName+"Sleep 10 секунд"); Thread.sleep (10000);} Catch (прерывание Extexception e) {}}} Частный класс kasknormal расширяет timertask {@Override public run () {system.out.print -krint -stime () gate -krint -kryrdtime (@word vidtime vidtime () waskrintlin выполнено ");}} частного класса TaskThrowException Extends TimerTask {@Override public void run () {System.out.println (getCurrentTime ()+": throw Exception "); Throw new Runtimeexception ();}} Private string getCurrentTime () {return newDateFormat (" hh: mm: sss ').2. ScheduleThreadPoolexeCutor
ScheduleThreadPoolexeCutor начал с JDK1.5 и был написан г -ном Дулеей. Он использует умную комбинацию ThreadPoolexeCutor и DelockQueue для завершения реализации многопоточного таймера, решая три вышеупомянутые дефекты, вызванные отдельным потоком в таймере.
Проблема 1 заключается в том, что последующие задачи не могут быть выполнены вовремя, поскольку отдельные потоки выполняются последовательно. Мы видим, что многопоточное может легко решить эту проблему. В то же время мы заметили, что время исполнения TaskUselongtime составляет 10 с (см. Последующий код). Мы рассчитали интервал задачи 5 секунд, но из-за результата мы обнаружили, что наш интервал выполнения задачи составляет 10 секунд, поэтому мы можем судить, что PradeLechReadPoolexeCutor работает в режиме для затрат на задание.
// задача 1: m_timer.scheduleatfixedrate (new Taskuselongtime (), 1000, 5000, TimeUnit.milliseconds); m_timer.scheduleatfixedrate (new TaskNormal (), 1000, 5000, TimeUnit.milliseconds); Запуск результата: 14:54:37: задача нормальная выполненная 14:54:37: Таймер спит 10 секунд 14:54:42: Задача нормальная выполненная 14:54:47: Задача Нормальная выполненная 14:54:47: нормальное выполнение задачи.
В вопросе 2 мы обнаружили, что когда исключение брошено, выполнение задачи не влияет на работу других задач. В то же время мы обнаружили, что наше исключение не было брошено в результате пробега. Это связано с тем, что класс PradeLechReadPoolexeCutor вернет результат запуска запланированного плана после выполнения задачи времена. Будет ли результат успешным или есть исключения, он будет сохранен здесь.
// задача 2: m_timer.scheduleatfixedrate (New TaskThrowException (), 1000, 5000, TimeUnit.milliseconds); m_timer.scheduleatfixedrate (new TaskNormal (), 1000, 5000, TimeUnit.milliseconds); Запуск Результат: 14:58:36: Выбросьте исключение 14:58:36: задача нормальная выполненная 14:58:41: Задача нормальная выполненная 14:58:46: Задача нормальная выполненная 14:58:46: Задача нормальная выполненная 14:58:46: нормальное выполнение задачи.
Вопрос 3 Поскольку он многопоточный, мы можем убедиться, что наши задачи времени могут быть выполнены одновременно.
// Проблема 3: m_timer.scheduleatfixedrate (новый TaskUselongtime («Timer1»), 1000, 5000, TimeUnit.milliseconds); m_timer.scheduleatfixedrate (new Taskuselongtime ("timer2"), 1000, 5000, timeUnit.milliseconds); Результат бега: 15:01:12: Timer1 спит 10 секунд 15:01:12: Timer2 спит 10 секунд 15:01:22: Timer2 спит 10 секунд 15:01:22: Timer2 сон 10 секунд 15:01:22: Timer2 - 10 секунд 15:01:22: Timer2 Спит 10 секунд 15:01:22 :22 :22 :22 :22 :22: 15:01:22: Таймер2 спит 10 секунд 15:01:22: Таймер2 спит 10 секунд 15:01:22: Таймер2 спит 10 секунд 15:01:22: Timer2 спит 10 секунд 15:01:22: Timer2 сон 10 секунды 15:01:22: Timer2 - 10 секунд 15:01 :2: 2: 15:01:22: Таймер2 спит 10 секунд 15:01:22: Таймер2 спит 10 секунд 15:01:22: Таймер 2 спит 10 секунд 15:01:22: Timer2 спит 10 секунд 15:01:22: Timer2 спит 10 секунд 15:01: секунды 15:01:22: Timer111111: 3: 31: 3: 31: 3: 31: 3: 31: 3:01: 3:01: 3:01: 3:01: 3:01: 3:01: 3: 3: секунды 15:01:32: Timer2 спит 10 секундПодробный код:
пакет timer_test; import java.text.simpledateformat; import java.util.date; import java.util.concurrent.callable; import java.util.concurrent.scheduledthreadpoolexecutor; import java.util.concurrent.timeUnit; WarededThreadPoolexeCutor m_timer = new PredicleDThreadPoolexeCutor (10); public static void main (string [] args) {shareLeThreadPoolexeCutortest timertest = new graduleThreadPoolexEcutortest (); timertest.test () {thread.seex (100000); {timertest.shutdown ();}} public void shutdown () {m_timer.shutdown ();} public void test () {// Вопрос 1: // m_timer.scheduleatefixedrate (new Taskuselongtime (), 1000, 5000, timeUnit.milliseconds); // m_timer.scheduleatfixedrate (new TaskNormal (), 1000, 5000, TimeUnit.milliseconds); // Вопрос 2: // m_timer.scheduleatfixedrate (New TaskThrowException (), 1000, 5000, TimeUnit.milliseconds); // m_timer.scheduleatfixedrate (new TaskNormal (), 1000, 5000, TimeUnit.milliseconds); // Проблема 3: m_timer.scheduleatfixedrate (новый TaskUselongtime («Timer1»), 1000, 5000, TimeUnit.milliseconds); m_timer.scheduleatefixedrate (новый TaskUselongtime («Timer2», 1000, 5000, TimeUnit.milliseconds); Callable <Integer>, Runnable {Private String m_taskName = "timer"; private TaskUselongtime () {} private TaskUselongtime (String TaskName) {m_taskName = taskName;} public void run () {try {System.out.println (getCurrentTime ()+":"+m_tAm секунды "); thread.sleep (10000);} Catch (прерывание Extexception e) {}} public integer call () throws exception {run (); return 0;}@suppresswarnings (" unared ") частный класс TaskNormal Reflestipments Callable <Integer>, Runnable {public integer call () throws exception exection {) run run run ();) run run run run run run run ();););) {System.out.println (getCurrentTime ()+": задача нормальная выполненная");}}@PuppressWarnings («неиспользованный») частное класс задача реализует Callable <Integer>, Runnable {public Integer Call () Throws Exception {System.out.println (getCurrentTime ()+": throw execult"); run () {System.out.println (getCurrentTime ()+": throw Exception"); бросить новый runtimeexception ();}} private String getCurrentTime () {return new SimpleDateFormat ("HH: MM: SS").Суммировать
Вышеупомянутое дело о кратком обсуждении этой статьи об истории развития таймеров Java, и я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на этот сайт:
Java реализует простой анализ кода таймера
Принцип и реализация таймера многопоточного таймера Java
Пример кода, как использовать таймер Java Timer
Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!