ThreadPoolTaskExecutor corePoolSize לעומת maxPoolSize

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

האביב ThreadPoolTaskExecutor הוא JavaBean המספק הפשטה סביב a java.util.concurrent.ThreadPoolExecutor למשל וחושף אותו כמעיין org.springframework.core.task.TaskExecutor. יתר על כן, הוא ניתן להגדרה גבוהה באמצעות המאפיינים של corePoolSize, maxPoolSize, queueCapacity, allowCoreThreadTimeOut ו keepAliveSeconds. במדריך זה, נסתכל על corePoolSize ו maxPoolSize נכסים.

2. corePoolSize לעומת. maxPoolSize

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

2.1. corePoolSize

ה corePoolSize הוא מספר העובדים המינימלי שיישאר בחיים בלי לתזמן. זהו מאפיין הניתן להגדרה של ThreadPoolTaskExecutor. אולם, ה ThreadPoolTaskExecutor הפשטה מציינת שמגדירה ערך זה לבסיס java.util.concurrent.ThreadPoolExecutor. לשם הבהרה, כל הנושאים עשויים להפסיק זמן - ובכך לקבוע את הערך של corePoolSize לאפס אם הגדרנו allowCoreThreadTimeOut ל נָכוֹן.

2.2. maxPoolSize

לעומת זאת, ה maxPoolSize מגדיר את המספר המרבי של האשכולות שאי פעם ניתן ליצור. באופן דומה, ה maxPoolSize רכוש של ThreadPoolTaskExecutor גם מאציל את ערכו לבסיס java.util.concurrent.ThreadPoolExecutor. להבהיר, maxPoolSize תלוי ב queueCapacity בתוך זה ThreadPoolTaskExecutor תיצור שרשור חדש רק אם מספר הפריטים בתור שלו יעלה queueCapacity.

3. אז מה ההבדל?

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

כאשר אנו מגישים משימה חדשה ל ThreadPoolTaskExecutor, זה יוצר חוט חדש אם פחות מ- corePoolSize האשכולות פועלים, גם אם יש אשכולות סרק בבריכה, או אם פחות מ- maxPoolSize האשכולות פועלים והתור מוגדר על ידי queueCapacity זה מלא.

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

4. דוגמאות

ראשית, נניח שיש לנו שיטה שמבצעת שרשורים חדשים, מ- ThreadPoolTaskExecutor, בשם startThreads:

public void startThreads (ThreadPoolTaskExecutor taskExecutor, CountDownLatch countDownLatch, int numThreads) {for (int i = 0; i {try {Thread.sleep (100L * ThreadLocalRandom.current (). nextLong (1, 10)); countDownLatch.countDown () ;} לתפוס (InterruptedException e) {Thread.currentThread (). interrupt ();}}); }}

בואו נבדוק את תצורת ברירת המחדל של ThreadPoolTaskExecutor, המגדיר א corePoolSize של חוט אחד, בלתי מוגבל maxPoolSize, ובלתי מוגבלת queueCapacity. כתוצאה מכך, אנו מצפים שלא משנה כמה משימות נתחיל, רק שרשור אחד יפעל:

@Test ציבורי בטל כאשרUsingDefaults_thenSingleThread () {ThreadPoolTaskExecutor taskExecutor = ThreadPoolTaskExecutor חדש); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = CountDownLatch חדש (10); this.startThreads (taskExecutor, countDownLatch, 10); בעוד (countDownLatch.getCount ()> 0) {Assert.assertEquals (1, taskExecutor.getPoolSize ()); }}

עכשיו, בואו לשנות את corePoolSize לכל היותר חמישה שרשורים וודא שהוא יתנהג כפי שפורסם. כתוצאה מכך, אנו מצפים כי יתחילו חמישה שרשורים ולא משנה מספר המשימות שהוגשו ל ThreadPoolTaskExecutor:

@Test ציבורי בטל כאשרCorePoolSizeFive_thenFiveThreads () {ThreadPoolTaskExecutor taskExecutor = ThreadPoolTaskExecutor חדש (); taskExecutor.setCorePoolSize (5); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = CountDownLatch חדש (10); this.startThreads (taskExecutor, countDownLatch, 10); בעוד (countDownLatch.getCount ()> 0) {Assert.assertEquals (5, taskExecutor.getPoolSize ()); }}

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

@Test ציבורי בטל כאשרCorePoolSizeFiveAndMaxPoolSizeTen_thenFiveThreads () {ThreadPoolTaskExecutor taskExecutor = ThreadPoolTaskExecutor חדש (); taskExecutor.setCorePoolSize (5); taskExecutor.setMaxPoolSize (10); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = CountDownLatch חדש (10); this.startThreads (taskExecutor, countDownLatch, 10); בעוד (countDownLatch.getCount ()> 0) {Assert.assertEquals (5, taskExecutor.getPoolSize ()); }}

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

@Test הציבור בטל כאשרCorePoolSizeFiveAndMaxPoolSizeTenAndQueueCapacityTen_thenTenThreads () {ThreadPoolTaskExecutor taskExecutor = ThreadPoolTaskExecutor חדש (); taskExecutor.setCorePoolSize (5); taskExecutor.setMaxPoolSize (10); taskExecutor.setQueueCapacity (10); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = CountDownLatch חדש (20); this.startThreads (taskExecutor, countDownLatch, 20); בעוד (countDownLatch.getCount ()> 0) {Assert.assertEquals (10, taskExecutor.getPoolSize ()); }}

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

5. מסקנה

ThreadPoolTaskExecutor הוא הפשטה עוצמתית סביב א java.util.concurrent.ThreadPoolExecutor, המספק אפשרויות להגדרת התצורה של corePoolSize, maxPoolSize, ו queueCapacity. במדריך זה, הסתכלנו על corePoolSize ו maxPoolSize מאפיינים, כמו גם כיצד maxPoolSize עובד במקביל queueCapacity, המאפשר לנו ליצור מאגרי חוטים בקלות לכל מקרה שימוש.

כמו תמיד, אתה יכול למצוא את הקוד הזמין ב- Github.


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