Java ExecutorService הוא הממשק המאפשר לנו לבצע משימות על שרשורים באופן אסינכרוני. ממשק Java ExecutorService קיים בחבילת java.util.concurrent. ה-ExecutorService עוזר בשמירה על מאגר שרשורים ומקצה להם משימות. זה גם מספק את המאפשר לעמוד בתור משימות עד שיהיה שרשור פנוי זמין אם מספר המשימות גדול מהשרשורים הזמינים.
שיטות של Java ExecutorService
שיטה | תיאור |
---|---|
בוליאני awaitTermination (פסק זמן ארוך, יחידת TimeUnit) | שיטה זו חוסמת את המשימה להיכנס ל-ExecutorService עד שכל המשימות הושלמו לאחר בקשת הכיבוי, או שהפסקה הנתונה מתרחשת, או שהשרשור הנוכחי מופסק, המוקדם מביניהם. |
רשימה | שיטה זו מבצעת את רשימת המשימות שניתנו ומחזירה את רשימת העתידים המכילה את התוצאות של כל המשימות בסיום. |
רשימה | שיטה זו מבצעת את רשימת המשימות שניתנו ומחזירה את רשימת העתידים המכילה את התוצאות של כל המשימות בסיום או פג תוקף הזמן הקצוב, המוקדם מביניהם. |
T invokeAny(Collection extends Callable>משימות) | שיטה זו מבצעת את רשימת המשימות שניתנו ומחזירה את התוצאה של משימה אחת שמסתיימת מבלי לזרוק שום חריגה. |
T invokeAny(Collection extends Callable>משימות, זמן קצוב ארוך, יחידת TimeUnit) | שיטה זו מבצעת את רשימת המשימות שניתנו ומחזירה את התוצאה של משימה אחת שמסתיימת מבלי לזרוק שום חריגה לפני שפג הזמן הקצוב. |
boolean isShutdown() | שיטה זו מחזירה אם המבצע הנתון נסגר או לא. |
boolean isTerminated() | שיטה זו מחזירה true אם כל המשימות בוצעו לאחר הכיבוי. |
void shutdown() | שיטה זו מאפשרת השלמת משימות שהוגשו בעבר ל-ExecutorService ואינה מאפשרת לקבל משימות אחרות. |
רשימה shutdownNow() | שיטה זו עוצרת את כל המשימות הפועלות באופן פעיל, עוצרת את הביצוע של משימות בתור, ומחזירה את רשימת המשימות שנמצאות בתור. |
הגשה עתידית (משימה ניתנת להתקשרות) | שיטה זו מגישה משימה להחזרת ערך לביצוע ומחזירה את העתיד, המייצג את התוצאה הממתינה של המשימה. |
הגשה עתידית (משימה ניתנת להרצה) | שיטה זו שולחת משימה לביצוע ומחזירה Future המייצגת משימה זו. זה מחזיר לאפס עם סיום מוצלח. |
הגשה עתידית (משימה ניתנת להרצה, תוצאת T) | שיטה זו שולחת משימה לביצוע ומחזירה Future המייצגת משימה זו. |
תוכנית פשוטה של Java ExecutorService
public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); executorService.shutdown(); } }
תְפוּקָה:
בתוכנית זו, אנו יוצרים ExecutorService עם עשרה שרשורים ומקצים לו מימוש אנונימי שניתן להרצה אשר מבצע משימה להדפסת 'ExecutorService' ולאחר שהמשימה שלו מסתיימת, אנו מכבים את שירות ה-executor.
כיצד להשתמש ב- Java ExecutorService
הפעלת ExecutorService
אנו יכולים להשתמש ב-Java ExecutorService כדי ליצור שרשור בודד, מאגר שרשורים או מאגר שרשורים מתוזמן. מחלקת ה-Executors מספקת שיטות מפעל ליצירת מופע של ExecutorService באופן הבא-
רשימות css
ExecutorService executorService1 = Executors.newSingleThreadExecutor(); //Creates //a ExecutorService object having a single thread. ExecutorService executorService2 = Executors.newFixedThreadPool(10); // Creates a //ExecutorService object having a pool of 10 threads. ExecutorService executorService3 = Executors.newScheduledThreadPool(10); //Creates a scheduled thread pool executor with 10 threads. In scheduled thread //pool, we can schedule tasks of the threads.
הקצאת משימות ל-ExecutorServices
כדי להקצות משימה ל-ExecutorService, אנו יכולים להשתמש בשיטות הבאות-
- בצע (משימה ניתנת להרצה)
- submit(משימה ניתנת להרצה) / submit(משימה ניתנת להתקשרות)
- invokeAny(Collection extends Callable>משימות)
- invokeAll(Collection extends Callable>משימות)
דוגמה להקצאת משימה ל-ExecutorService באמצעות שיטת execute()
java שווה
שיטת ה-execute() של Java ExecutorService לוקחת אובייקט הניתן להרצה ומבצעת את המשימה שלו באופן אסינכרוני. לאחר ביצוע שיטת הקריאה לביצוע, אנו קוראים לשיטת shutdown, אשר חוסמת כל משימה אחרת לעמוד בתור ב-executorService.
public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); executorService.shutdown(); } }
תְפוּקָה:
ExecutorService
דוגמה להקצאת משימה ל-ExecutorService באמצעות submit()
המתודה submit() לוקחת אובייקט שניתן להרצה ומחזירה אובייקט Future. אובייקט זה משמש מאוחר יותר כדי לבדוק את המצב של Runnable בין אם הוא השלים את הביצוע או לא.
public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.submit(new Runnable() { @Override public void run() { System.out.println('ExecutorService'); } }); } }
דוגמה להקצאת משימה ל-ExecutorService באמצעות שיטת invokeAny()
השיטה invokeAny() לוקחת אוסף של אובייקטים Callablle או אובייקטים של מחלקות המטשמות Callable. שיטה זו מחזירה את האובייקט העתידי של האובייקט הניתן להתקשרות אשר מבוצע בהצלחה תחילה.
מה זה 25 מתוך 100
public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<callable> callables = new HashSet<callable>(); callables.add(new Callable() { public String call() throws Exception { return 'Task 1'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 2'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 3'; } }); String result = executorService.invokeAny(callables); System.out.println('result = ' + result); executorService.shutdown(); } } </callable></callable>
תְפוּקָה:
result = Task 1
התוצאה מאחסנת את משימה 1 כשהאובייקט הראשון הניתן להתקשרות מבוצע בהצלחה ראשון.
דוגמה להקצאת משימה ל-ExecutorService באמצעות שיטת invokeAll()
j e s t
השיטה invokeAll() לוקחת אוסף של אובייקטים שניתן להתקשר עם משימות ומחזירה רשימה של אובייקטים עתידיים המכילים את התוצאה של כל המשימות.
public class ExecutorServiceExample { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newSingleThreadExecutor(); Set<callable> callables = new HashSet<callable>(); callables.add(new Callable() { public String call() throws Exception { return 'Task 1'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 2'; } }); callables.add(new Callable() { public String call() throws Exception { return 'Task 3'; } }); java.util.List<future> futures = executorService.invokeAll(callables); for(Future future : futures){ System.out.println('future.get = ' + future.get()); } executorService.shutdown(); } } </future></callable></callable>
תְפוּקָה:
future.get = Task 1 future.get = Task 3 future.get = Task 2
כיצד לכבות את ExecutorService
ברגע שסיימנו עם המשימות שלנו שניתנו ל-ExecutorService, אז עלינו לכבות אותו מכיוון ש-ExecutorService מבצע את המשימה על שרשורים שונים. אם לא נסגור את ה-ExecutorService, השרשורים ימשיכו לרוץ, וה-JVM לא ייסגר.
תהליך הכיבוי יכול להיעשות בשלוש השיטות הבאות-
- שיטת shutdown().
- שיטת shutdownNow().
- שיטת awaitTermination().