תזמון בג'קרטה EE

1. סקירה כללית

במאמר קודם הדגמנו כיצד לתזמן משימות באביב באמצעותמתוזמןביאור. במאמר זה נדגים כיצד להשיג אותו באמצעות שימוש שירות הטיימר ביישום EE בג'קרטה לכל מקרה שהוצג במאמר הקודם.

2. אפשר תמיכה בתזמון

ביישום EE של ג'קרטה, אין צורך לאפשר תמיכה במשימות מתוזמנות. שירות הטיימר הוא שירות מנוהל על ידי מיכל המאפשר ליישומים להתקשר לשיטות המתוזמנות לאירועים מבוססי זמן. כדוגמה, ייתכן שיישום יצטרך להריץ כמה דוחות יומיים בשעה מסוימת על מנת ליצור נתונים סטטיסטיים.

ישנם שני סוגים של טיימרים:

  • טיימרים פרוגרמטיים: ניתן להזריק את שירות הטיימר לכל שעועית (למעט שעועית מושבתית) ויש להציב את ההיגיון העסקי בשיטה המסומנת עם @פסק זמן. ניתן לאתחל את הטיימר על ידי שיטה המסומנת @PostConstruct מהשעועית או שניתן לאתחל אותה רק על ידי קריאת שיטה.
  • טיימרים אוטומטיים: ההיגיון העסקי ממוקם בכל שיטה שמסומנת עליה @לוח זמנים אוֹ @ לוחות זמנים. טיימרים אלה מאותחלים ברגע שהיישום מתחיל.

אז בואו נתחיל בדוגמה הראשונה שלנו.

3. קבע משימה עם עיכוב קבוע

באביב זה נעשה פשוט באמצעות מתוזמן @ (fixedDelay = 1000) ביאור. במקרה זה, משך הזמן בין סוף הביצוע האחרון לתחילת הביצוע הבא קבוע. המשימה ממתינה תמיד עד לסיום הקודמת.

לעשות את אותו הדבר בדיוק בג'קרטה EE זה קצת יותר קשה להשגה מכיוון שאין מנגנון מובנה דומה המסופק, עם זאת, ניתן ליישם תרחיש דומה עם מעט קידוד נוסף. בואו נסתכל כיצד זה נעשה:

@Singleton מחלקה ציבורית FixedTimerBean {@EJB פרטי WorkerBean workerBean; @Lock (LockType.READ) @Schedule (second = "* / 5", minute = "*", hour = "*", persistent = false) בטל ציבורי ב- Schedule () זורק את InterruptedException {workerBean.doTimerWork (); }} 
@Singleton בכיתה ציבורית WorkerBean {פרטי AtomicBoolean עסוק = AtomicBoolean חדש (שקר); @Lock (LockType.READ) חלל ציבורי doTimerWork () זורק InterruptedException {if (! Busy.compareAndSet (false, true)) {return; } נסה את {Thread.sleep (20000L); } סוף סוף {busy.set (false); }}}

כפי שניתן לראות טיימר מתוכנן להיות מופעל כל חמש שניות. עם זאת, השיטה שהופעלה במקרה שלנו הדמה זמן תגובה של 20 שניות בשיחה לִישׁוֹן() על הזרם פְּתִיל.

כתוצאה מכך, המכולה תמשיך להתקשר doTimerWork () כל חמש שניות אבל המצב שהוצב בתחילת השיטה, busy.compareAndSet (שקר, נכון), יחזור מיד אם השיחה הקודמת לא הסתיימה. בכך אנו מבטיחים שהמשימה הבאה תבוצע רק לאחר שהמשימה הקודמת הסתיימה.

4. קבע משימה בתעריף קבוע

אחת הדרכים לעשות זאת היא להשתמש בשירות הטיימר המוזרק באמצעות שימוש @מַשׁאָב והוגדר בשיטה המאושרת @PostConstruct. השיטה עם הערות עם @פסק זמן ייקרא כאשר יפוג הטיימר.

כאמור במאמר הקודם תחילת ביצוע המשימה לא מחכה לסיום הביצוע הקודם. יש להשתמש באפשרות זו כאשר כל ביצוע של המשימה הוא עצמאי. קטע הקוד הבא יוצר טיימר שמופעל בכל שנייה:

@Startup @Singleton בכיתה הציבורית אירוע אירוע אירוע ProgrammaticAtFixedRateTimerBean {@Inject; @Resource TimerService timerService; @PostConstruct חלל ציבורי מאותחל () {timerService.createTimer (0,1000, "כל טיימר שני ללא עיכוב"); } @ Timeout ציבורי ריק חלל programmaticTimout (טיימר טיימר) {event.fire (TimerEvent חדש (timer.getInfo (). ToString ())); }}

דרך נוספת היא להשתמש מתוזמן ביאור. בקטע הקוד הבא אנו מפעילים טיימר כל חמש שניות:

@Startup @Singleton מחלקה ציבורית ScheduleTimerBean {@ אירוע אירוע אירוע; @Schedule (שעה = "*", דקה = "*", שנייה = "* / 5", מידע = "כל 5 שניות טיימר") חלל ציבורי באופן אוטומטי מתוזמן (טיימר טיימר) {fireEvent (טיימר); } חלל פרטי fireEvent (טיימר טיימר) {event.fire (TimerEvent חדש (timer.getInfo (). toString ())); }}

5. קבע משימה עם עיכוב ראשוני

אם תרחיש השימוש שלך דורש שהטיימר יתחיל בעיכוב, נוכל לעשות זאת גם. במקרה זה ג'קרטה EE מאפשרת שימוש בשירות הטיימר. בואו נסתכל על דוגמה שבה לטיימר יש עיכוב ראשוני של 10 שניות ואז יורה כל חמש שניות:

@Startup @Singleton בכיתה הציבורית אירוע אירוע ProgrammaticWithInitialFixedDelayTimerBean {@Inject; @Resource TimerService timerService; @PostConstruct חלל ציבורי אתחל () {timerService.createTimer (10000, 5000, "השהה 10 שניות ואז כל טיימר של 5 שניות"); } @ Timeout ציבורי ריק חלל programmaticTimout (טיימר טיימר) {event.fire (TimerEvent חדש (timer.getInfo (). ToString ())); }}

ה createTimer השיטה המשמשת במדגם שלנו היא באמצעות החתימה הבאה createTimer (Long initialDuration, interval intervalDuration, java.io. מידע ניתן לשינוי) איפה initialDuration הוא מספר האלפיות השנייה שחייבות לעבור לפני הודעת תפוגת הטיימר הראשונה ו- intervalDuration הוא מספר האלפיות השנייה שחייבות לעבור בין הודעות על תפוגת טיימר.

בדוגמה זו אנו משתמשים ב- initialDuration של 10 שניות ו- intervalDuration של חמש שניות. המשימה תבוצע בפעם הראשונה לאחר initialDuration ערך והוא ימשיך להתבצע על פי intervalDuration.

6. תזמן משימה באמצעות ביטויי קרון

כל מתזמנים שראינו, הן פרוגרמטיים והן אוטומטיים, מאפשרים שימוש בביטויים cron. בואו נראה דוגמה:

@Schedules ({@Schedule (dayOfMonth = "Last"), @Schedule (dayOfWeek = "Fri", hour = "23")}) חלל ציבורי doPeriodicCleanup () {...}

בדוגמה זו השיטה doPeriodicCleanup () ייקרא בכל יום שישי בשעה 23:00 וביום האחרון של החודש.

7. מסקנה

במאמר זה בדקנו דרכים שונות לתזמן משימות בסביבת EE בג'קרטה באמצעות כנקודת מוצא מאמר קודם בו נעשו דגימות באמצעות אביב.

ניתן למצוא דוגמאות קוד במאגר GitHub.