كلاهما موجودان في الحزمة التخديمية java.util
كلاهما يعملان مع منصة عمل جافا التقليدية J2SE ومنصة عمل جافا إصدار الأجهزة الجوالة J2ME
تتبع المثال التالي سيوضح كل شيء .
import java.util.*;
public class MyClass extends TimerTask{
public MyClass() { }
public void run(){
هنا تضع الكود المعبر عن السلوك الذي تريد التحكم زمنيا بتنفيذه..
مثلا طباعة عبارة "هذا من فضل ربي"
System.out.println("هذا من فضل ربي");
}
public static void main(String[] args) {
MyClass myclass = new MyClass();
Timer mytimer=new Timer();
//******************* اختر احد هذه الطرق ********************//
mytimer.schedule(myclass,2000);
mytimer.schedule(myclass,2000,5000);
mytimer.scheduleAtFixedRate(myclass,2000,5000);
mytimer.schedule(myclass,new Date());
mytimer.schedule(myclass,new Date(),2000);
mytimer.scheduleAtFixedRate(myclass,new Date(),2000);
//******************************************//
}
}عمليا يتلخص التعامل مع هذه الحزمة بالخطوات التالية :
- استيراد الحزمة التخديمية java.util
- جعل صفك (MyClass .. على سبيل المثال) يرث extends الصف المجرد TimerTask الذي يمثل implements الواجهة Runnable الحاوية على اجرائية وحيدة run() علينا تمثيلها ( كتابة كود يمثل سلوكها) في الصف MyClass
- انشاء غرض عن الصف Timer
- انشاء غرض عن صفك MyClass
- استدعاء أحد الطرق التالية (موضحة مع الكود) الخاصة بالصف Timer التي تمرر لها كبرامتر أول اسم صفك (صف يرث TimerTask) تقبله الطريقة بسبب خاصية تعددية الأشكال
شرح الطرق
mytimer.schedule(myclass,2000);
يعمل على جعل السلوك المراد التحكم في تنفيذه زمنيا الموجود في الطريقة run() التابعة للغرضmyclass المنشأ عن صف ما يرث الصف TimerTask
يتنفذ مره بعد مرور زمن أي تأخير مقداره 2000 ميللي ثانية أي ثانيتان
mytimer.schedule(myclass,2000,5000);
تعمل على جعل السلوك المذكور يتنفذ مرارا وتكرارا(هنا كل 5000 ميللي ثانية أي 5 ثواني) بتأخير ثابت للتنفيذ
أي يبدأ تنفيذ السلوك المذكور بعد مرور 2000 ميللي ثانية (أي ثانيتان) من لحظة تشغيل البرنامج ... تنفيذ 1
وبعد انتهاء عملية التنفيذ بغض النظر عن الزمن الذي استغرقه في التنفيذ ب5 ثواني (وهي الفترة الزمنية الفاصلة بين تنفيذين ) يجري تأخير مره اخرى مقداره ثانيتان ومن ثم اعادة تنفيذ السلوك ذاته مره اخرى ..
تنفيذ 2
وهكذا ..تأخير..تنفيذ ومن ثم فترة فاصلة ثم تأخير فتنفيذ .. طالما ان البرنامج في حالة تشغيل
حتى يتم اغلاق البرنامج أو حدوث حدث (ضغط زر توقف مثلا) يسبب استدعاء الطريقة :
mytimer.cancel();
التي توقف تنفيذ السلوك المذكور لحظة استدعائها .
عملية التنظيم الزمني لأجل أي تنفيذ (تنفيذ 2 مثلا ) تتعلق بزمن التنفيذ الحقيقي للتنفيذ الذي قبله (تنفيذ 1)
حيث قد يستغرق التأخير في بعض مرات التنفيذ زمنا أكثر من الزمن الذي قدرته لظروف معينة قد تتعلق بالذاكرة ونظام التشغيل ... الخ .
مما يؤدي الى ان التنفيذات التالية له ستتأخر عن موعدها .
(قد تتوقع مثلا ان يتم التنفيذ التاسع تمام الساعة السادسة طبقا لجدولتك الزمنية للسلوك المذكور وتتفاجأ انه لم يتنفذ في موعده بل متأخرا عنه )
تختار هذه الطريقة عندما لا يهمك موضوع الضبط الدقيق للوقت
mytimer.scheduleAtFixedRate(myclass,2000,5000);
تعمل على جعل السلوك المذكور يتنفذ مرارا وتكرارا(هنا كل 5000 ميللي ثانية أي 5 ثواني) بمعدل ثابت للتنفيذ
أي يبدأ تنفيذ السلوك المذكور بعد مرور ثانيتان كزمن تأخير من لحظة تشغيل البرنامج
ومن ثم فترة زمنية فاصلة مقدارها 5 ثواني .. وهكذا
تماما مثل الألية السابقة
ولكن الإختلاف هنا انه كل تنفيذ يتم بالرجوع الى الجدولة الزمنية المبدئية التي وضعتها
ولا علاقة لأي تنفيذ بأي تنفيذ سابق له (ستلاحظ بدء التنفيذ التاسع تمام الساعة السادسة تماما طبقا لحساباتك ) .
mytimer.schedule(myclass,new Date());
يجري تنفيذ السلوك المذكور حال حلول التاريخ المذكور بدون تأخير وان كان التاريخ قد مضى (لم يكن برنامجك شغال وقتها) يجري التنفيذ حال فتح برنامجك اول مره بعد هذا التاريخ .
mytimer.schedule(myclass,new Date(),2000);
اذا حل التاريخ المذكور يجري تأخير مقداره ثانيتان قبل بدء تنفيذ السلوك المذكور
mytimer.scheduleAtFixedRate(myclass,new Date(),2000);
يجري تنفيذ السلوك المذكور كل ثانيتان بدون زمن تأخير ابتداء من التاريخ المذكور
مع مراعاة الزمن المضبوط كما ذكرنا سابقا (الفرق بين schedule و scheduleAtFixedRate )
ملاحظة : mytimer.cancel(); التي توقف تنفيذ السلوك المذكور لحظة استدعائها ... عملها ينطبق على كل الطرق السابقة .
والشكل التالي يمثل مخطط الصفوف الذي يوضح الاستخدام العملي للصف المؤقت ومؤقت الأعمال .

كي لا تتعقد الأمور وتبقي صفك ذو السلوك المطلوب جدولته زمنيا منفصلا عن اجراءات الجدولة الزمنية واستدعاءاتها بالاستعانة بصف ثالث TestClass يقوم بعمل غرض عن صفك وعن الصف Timer ويستدعي
اجراءات الجدولة .. ولكن لاغنى من ان تجعل صفك يرث TimerTask وتحدد السلوك المطلوب جدولته زمنيا ضمن run() بالشكل التالي :



