في التطوير ، غالبًا ما نحتاج إلى بعض العمليات الدورية ، مثل إجراء عملية معينة كل بضع دقائق. في هذا الوقت ، نحتاج إلى ضبط مؤقت. الطريقة الأكثر ملاءمة وكفاءة لتنفيذها في Java هي استخدام فئة أدوات java.util.timer ، ثم جدولة مهمة java.util.timertask.
Timer هي أداة تستخدمها لترتيب المهام التي سيتم تنفيذها في مؤشرات ترابط الخلفية لاحقًا. يمكن تنفيذ المهام مرة واحدة ، أو يمكن تنفيذها بشكل متكرر. إنه في الواقع موضوع يحدد جدولة التوقيتات التي تملكها الجدولة المحددة.
Timertask هو فئة مجردة يتم ترتيب فئاته الفرعية بواسطة Timer كمهام يتم تنفيذها أو تكرارها. في الواقع ، إنه فئة ذات طريقة تشغيل ، ويتم وضع الرمز الذي يجب تنفيذه بانتظام في هيئة طريقة التشغيل.
أطلقت Java Timer Class Timer في JDK1.3 ، ثم طورت Doulea حديثًا مجموعة ScheduleThreadPoolexecutor التي تدعم متعدد الخيوط بعد JDK1.5. انطلاقًا من أداء الأخير ، يمكننا التفكير في استبدال مؤقت تمامًا.
المقارنة بين المؤقت و SchedulethReadPoolexecutor:
1. يبدأ الموقت بـ JDK1.3. مبدأها هو استخدام صفيف timertask كقائمة انتظار لإضافة جميع مهام التوقيت إلى قائمة الانتظار هذه. ثم ابدأ موضوعًا. عندما تكون قائمة الانتظار فارغة ، سيتم حظر الخيط. عندما تكون هناك بيانات في قائمة الانتظار ، سيقوم مؤشر الترابط بإزالة timertask للحكم
سواء كان الوقت محدثًا ، تبدأ المهمة في التشغيل إذا كان وقت التشغيل أقل من أو يساوي الوقت الحالي. نظرًا لطبيعة الخيط الفردي ، فإنه يجلب العديد من المشكلات (رمز مفصل لاحقًا):
أولاً ، عندما تكون المهام التي نضيفها إلى الموقت تستغرق وقتًا طويلاً ، نظرًا لأن هذا المؤقت ينفذ مهام المؤقت بطريقة متتابعة لخيط واحد ، فسيؤثر ذلك على التنفيذ في الوقت المناسب للمهام اللاحقة.
كود جافا
// مثال على المشكلة: m_timer.scheduleatfixedrate (جديد TaskUseLongtime () ، 1000 ، 5000) ؛ m_timer.scheduleAtfixedrate (New TaskNormal () ، 5000 ، 3000) ؛ النتيجة الجري: 14:44:29: الموقت ينام 10 ثوانٍ 14:44:39: الموقت نائم 14:44:39: الموقت نائم 10 ثانية 14:44:49: المهمة العادية تنفذ 14:44: المهمة العادية المنتجة 14:44: المهمة العادية تنفذ 14:44 14:44:49: تم تنفيذ المهمة العادية 14:44:49: الموقت ينام 10 ثوان تحليل النتائج: لا يمكن ضمان تشغيل المهمة المهمة مرة واحدة كل 3 ثوان ، يمكن أن تنتظر فقط TaskUselongtime بعد اكتماله.
ثانياً ، سيحصل مؤشر الترابط في المؤقت على استثناء InterruptedException فقط ، لذلك إذا لم تصل مهمة التوقيت المخصصة إلى استثناءات محتملة وتتسبب في إلقاء استثناء ،
// مثال 2: m_timer.schedule (TaskThrowException () ، 1000) ؛ M_TIMER.SCHEDULE (New TaskNormal () ، 2000) ؛ النتيجة تشغيل: 14:47:37: استثناء استثناء رمي في الموضوع "Timer-0" java.lang.runtimeexception في timer_test.timertest $ taskthrowexception.run (timertest.java:85) في java.util.timerthread.mainloop (timer.java:512) في java.util.timerthread.run (timer.java:462) تحليل النتائج: بعد إلقاء استثناء بمهمة ، لا يمكن أن تستمر المهمة المهمة اللاحقة في العمل.
سيؤدي ذلك إلى إيقاف خيط الموقت الخاص بنا ، بحيث لا يمكن تنفيذ المهام اللاحقة الأخرى.
ثالثًا ، لا يمكنه التعامل مع مهام التوقيت المتعددة التي تحدث في وقت واحد
// تحليل الأسئلة الثلاثة: m_timer.scheduleAtfixedrate (TaskUseSelongtime ("Timer1") ، 1000 ، 15000) ؛ m_timer.scheduleatfixedrate (TaskUseSelongtime ("Timer2") ، 1000 ، 15000) ؛ النتيجة الجري: 14:50:16: Timer1 ينام 10 ثوانٍ 14:50:26: Timer2 ينام 10 ثوانٍ 14:50:36: Timer2 ينام 10 ثوان تحليل النتائج: وقت بدء التشغيل الخاص بي بعد ثانية واحدة ، لكن وقت بدء التشغيل بين Timer1 و timer2 من الواضح أنه غير متسقمثال رمز:
حزمة timer_test ؛ استيراد java.text.simpleDateFormat ؛ استيراد java.util.date ؛ استيراد java.util.timer ؛ استيراد java.util.timertask ؛ timertest public {private final timer m_timer = new timer () ؛ عينة من المشكلة: m_timer.ScheduleAtfixedrate (TaskUseSelongtime () ، 1000 ، 5000) ؛ m_timer.ScheDuleAtfixedrate (New TaskNormal () ، 5000 ، 3000) // m_timer.schedule (New TaskNormal () ، 2000) ؛ // مثال 3: // m_timer.scheduleatfixedrate (TaskUseSelongtime جديد ("timer1") ، 1000 ، 5000) ؛ // m_timer.scheduleAtfixedRate (جديد TaskUseLongTime ("Timer2") ، 1000 ، 5000) ؛} فئة خاصة TaskUseSelongtime Extriding TimerTask {private string m_taskname = "timer" {try {system.out.println (getCurrentTime ()+":"+m_taskname+"ينام 10 ثوانٍ") ؛ thread.sleep (10000) ؛} catch (interruptededexception e) {}}} tasknormal extring timertask {override rot تم تنفيذه ") ؛}} فئة خاصة TaskThrowException يمتد timertask {Override public void run () {system.out.println (getCurrentTime ()+": رمي استثناء ")2.schedulethreadpoolexecutor
بدأ ScheduleThreadPoolexecutor بـ JDK1.5 وكتبه السيد Doulea. يستخدم المزيج الذكي من Threadpoolexecutor و DelayQueue لإكمال تنفيذ مؤقت متعدد الخيوط ، وحل العيوب الثلاثة المذكورة أعلاه الناتجة عن موضوع واحد في المؤقت.
المشكلة في السؤال 1 هي أنه لا يمكن إكمال المهام اللاحقة في الوقت المحدد لأن مؤشرات الترابط المفردة تنفذ بالتتابع. نرى أن متعدد الخيوط يمكن أن يحل هذه المشكلة بسهولة. في الوقت نفسه ، لاحظنا أن وقت تنفيذ TaskUseLongtime هو 10s (يرجى الاطلاع على الكود اللاحق). لقد قمنا بتوقيت فاصل المهمة البالغ 5 ثوان ، ولكن من النتيجة ، وجدنا أن فاصل تنفيذ المهام لدينا هو 10 ثوان ، حتى نتمكن من الحكم على أن SchedulethReadPoolexecutor يعمل في وضع لكل سلسلة.
// المشكلة 1: m_timer.scheduleAtfixedrate (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:
في السؤال 2 ، وجدنا أنه عندما يتم طرح الاستثناء ، فإن تنفيذ المهمة لا يؤثر على تشغيل المهام الأخرى. في الوقت نفسه ، وجدنا أن استثناءنا لم يتم إلقاؤه في نتيجة التشغيل. وذلك لأن فئة SchedulethReadPoolExecutor ستعيد نتيجة تشغيل SchedeDfuture بعد تنفيذ المهمة المحددة. سواء كانت النتيجة ناجحة أو كانت هناك استثناءات ، سيتم حفظها هنا.
// المشكلة 2: m_timer.scheduleatfixedrate (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:
السؤال 3 نظرًا لأنه متعدد الخيوط ، يمكننا التأكد من أنه يمكن تنفيذ مهام التوقيت لدينا في نفس الوقت.
// المشكلة 3: m_timer.ScheduleAtfixedrate (TaskUseSelongtime ("Timer1") ، 1000 ، 5000 ، timeUnit.MillisEconds) ؛ m_timer.scheduleatfixedrate (TaskUseSelongtime ("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: 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: Timer2 هو نائم 10 ثانية 15:01:22 15:01:22: Timer2 نائم 10 ثوانٍ 15:01:22: Timer2 نائم 10 ثوانٍ 15:01:22: Timer2 ينام 10 ثوانٍ 15:01:22: Timer2 ينام 10 ثوانٍ 15:01:22: Timer2 ينام 10 ثوانٍ 15:01: ثاني 15:01 الثواني 15:01:32: Timer2 ينام 10 ثوانٍرمز مفصل:
حزمة timer_test ؛ استيراد java.text.simpleDateFormat ؛ استيراد java.util.date ؛ استيراد java.util.concurrent.callable ScreduleThReadPoolExecutor m_timer = جديد screadThreadPoolExecutor (10) ؛ public static void main (string [] args) {schedulethreadpoolexecutortest timertest = new ScheduleTheReadPoolexUtest () ؛ timertest.test () ؛ {timertest.shutdown () ؛}} إيقاف التشغيل public void () {m_timer.shutdown () ؛} اختبار الفراغ العام () {// السؤال 1: // m_timer.scheduleatfixedrate (TaskusElongtime () ، 1000 ، 5000 ، timeUnit.milliseconds) ؛ // m_timer.scheduleAtfixedrate (New TaskNormal () ، 1000 ، 5000 ، timeUnit.milliseconds) ؛ // السؤال 2: // m_timer.scheduleatfixedrate (TaskThrowException () ، 1000 ، 5000 ، timeUnit.milliseconds) ؛ // m_timer.scheduleAtfixedrate (New TaskNormal () ، 1000 ، 5000 ، timeUnit.milliseconds) ؛ // المشكلة 3: m_timer.scheduleAtfixedRate (TaskUseSelongtime ("timer1") ، 1000 ، 5000 ، timeUnit.milliseconds) ؛ m_timer.scheduleAtfixedrate (TaskusElongtime ("Timer2") ، 1000 ، 5000 ، timeUnit.MilliseCondrate) ؛ callable <integer> ، runnable {private string m_taskname = "timer" ؛ private taskuseLongtime () {} private taskUseLongtime (string taskName) {m_taskname = taskName ؛} public void run () {try ثانية ") ؛ thread.sleep (10000) ؛} catch (interruptedException e) {}} call public integer call () رمي الاستثناء {run () {system.out.println (getCurrentTime ()+": Task Normal Exerved") ؛}}@cumpresswarnings ("unused") private class taskthrowexception تنفذ callable <teger> ، runNable Run () {system.out.println (getCurrentTime ()+": رمي استثناء") ؛ رمي جديد RunTimeException () ؛}} سلسلة خاصة getCurrentTime () {return new simpledateformat ("hh: mm: ss")لخص
ما سبق يدور حول النقاش الموجز لهذه المقالة حول تاريخ تطوير أجهزة ضبط الوقت Java ، وآمل أن يكون ذلك مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى هذا الموقع:
تقوم Java بتنفيذ تحليل رمز مؤقت بسيط
مبدأ وتنفيذ توقيت Java Multithed
مثال رمز على كيفية استخدام مؤقت Java Timer
إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!