תזמון עבודה מבוסס עדיפות בג'אווה

1. הקדמה

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

בואו נראה איך נוכל להשיג זאת בג'אווה - באמצעות a PriorityBlockingQueue.

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

בואו נגיד שיש לנו משרות שאנחנו רוצים לבצע על סמך העדיפות שלהן:

מעמד ציבורי מיישם את העבודה Runnable {private String jobName; פרטי JobPriority jobPriority; @ ביטול הפעלה בטלנית ציבורית () {System.out.println ("Job:" + jobName + "Priority:" + jobPriority); Thread.sleep (1000); // לדמות זמן ביצוע בפועל} // סטרים וקובעים סטנדרטיים}

למטרות הדגמה אנו מדפיסים את שם התפקיד ואת העדיפות ב- לָרוּץ() שיטה.

הוספנו גם לִישׁוֹן() כך שנדמה עבודה ארוכה יותר; בזמן שהמשימה מבוצעת, משרות נוספות ייצברו בתור העדיפות.

סוף כל סוף, JobPriority הוא enum פשוט:

enum הציבור JobPriority {HIGH, MEDIUM, LOW}

3. מותאם אישית משווה

עלינו לכתוב משווה המגדיר את הקריטריונים המותאמים אישית שלנו; ובג'אווה 8 זה טריוויאלי:

Comparator.comparing (Job :: getJobPriority);

4. מתזמן משרות עדיפות

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

מחלקה ציבורית PriorityJobScheduler {עדיף ExecutorService prioritJobPoolExecutor; private ExecutorService priorityJobScheduler = Executors.newSingleThreadExecutor (); פרטיות PriorityBlockingQueue PriorityQueue; PriorityJobScheduler ציבורי (מספר כולל שלם, שלם תור גודל) {priorityJobPoolExecutor = Executors.newFixedThreadPool (poolSize); PriorityQueue = PriorityBlockingQueue חדש (queueSize, Comparator.comparing (Job :: getJobPriority)); PriorityJobScheduler.execute (() -> {while (true) {נסה {priorityJobPoolExecutor.execute (PriorityQueue.take ());} לתפוס (InterruptedException e) {// חריג צריך הפסקה מיוחדת בטיפול;}}}); } לוח זמנים בטל ציבורי Job (Job job) {prioritQueue.add (job); }}

המפתח כאן הוא ליצור מופע של PriorityBlockingQueue שֶׁל עבודה הקלד עם משווה מותאם אישית. העבודה הבאה לביצוע נבחרת מהתור באמצעות לקחת() שיטה המאחזרת ומסירה את ראש התור.

קוד הלקוח פשוט צריך להתקשר אל לוח זמנים () - שמוסיף את התפקיד לתור. ה prioritQueue.add () עומד בתור המשרה במיקום המתאים בהשוואה למשרות הקיימות בתור, באמצעות JobExecutionComparator.

שים לב כי העבודות בפועל מבוצעות באמצעות נפרד שירות ExecutorService עם מאגר חוטים ייעודי.

5. הדגמה

לסיום, הנה הדגמה מהירה של המתזמן:

פרטי סטטי פרטי POOL_SIZE = 1; פרטי סטטי פרטי QUEUE_SIZE = 10; @ מבחן פומבי בטל כאשר MultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked () {Job job1 = Job new ("Job1", JobPriority.LOW); משרה עבודה 2 = משרה חדשה ("Job2", JobPriority.MEDIUM); Job job3 = משרה חדשה ("Job3", JobPriority.HIGH); משרה עבודה 4 = משרה חדשה ("Job4", JobPriority.MEDIUM); Job job5 = משרה חדשה ("Job5", JobPriority.LOW); משרה משרה 6 = משרה חדשה ("Job6", JobPriority.HIGH); PriorityJobScheduler pjs = PriorityJobScheduler חדש (POOL_SIZE, QUEUE_SIZE); pjs.scheduleJob (job1); pjs.scheduleJob (job2); pjs.scheduleJob (job3); pjs.scheduleJob (job4); pjs.scheduleJob (job5); pjs.scheduleJob (job6); // לנקות }

על מנת להדגים שהמשרות מבוצעות בסדר העדיפויות, שמרנו על מידת בריכה כמו 1 למרות שה- QUEUE_SIZE הוא 10. אנו מספקים עבודות בעדיפות משתנה למתזמן.

הנה פלט לדוגמא שקיבלנו לאחת הריצות:

משרה: Job3 עדיפות: HIGH משרה: Job6 עדיפות: HIGH משרה: Job4 עדיפות: MEDIUM משרה: Job2 עדיפות: MEDIUM משרה: משרה 1 עדיפות: LOW משרה: Job5 עדיפות: LOW

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

6. מסקנה

במדריך מהיר זה ראינו כיצד PriorityBlockingQueue יכול לשמש לביצוע עבודות בסדר עדיפות מותאם אישית.

כרגיל, ניתן למצוא קבצי מקור ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found