מוציאים לפועל newCachedThreadPool () לעומת newFixedThreadPool ()

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

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

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

2. בריכת חוטים במטמון

בואו נסתכל כיצד ג'אווה יוצרת מאגר אשכולים במטמון כאשר אנו מתקשרים Executors.newCachedThreadPool ():

Public Static ExecutorService newCachedThreadPool () {להחזיר ThreadPoolExecutor חדש (0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, SynchronousQueue חדש ()); }

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

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

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

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

2.1. השתמש במקרים

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

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

משימה הניתנת להתקשרות = () -> {long oneHundredMicroSeconds = 100_000; התחלתי זמן רב = System.nanoTime (); תוך כדי (System.nanoTime () - task started) .collect (toList ()); var result = cachedPool.invokeAll (משימות);

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

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

3. בריכת חוטים קבועה

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

ExecutorService ציבורי סטטי newFixedThreadPool (int nThreads) {להחזיר ThreadPoolExecutor חדש (nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, חדש LinkedBlockingQueue ()); }

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

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

4. קווי דמיון מצערים

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

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

בואו נראה מה קורה בעולם האמיתי.

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

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

בכל מקרה, ל יש שליטה רבה יותר על צריכת משאבים, מומלץ מאוד ליצור מותאם אישית ThreadPoolExecutor:

var boundedQueue = ArrayBlockingQueue חדש (1000); ThreadPoolExecutor חדש (10, 20, 60, SECONDS, boundedQueue, AbortPolicy חדש ()); 

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

5. מסקנה

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

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


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