ThreadPoolTaskExecutor corePoolSize vs. maxPoolSize

1. Prehľad

Pružina ThreadPoolTaskExecutor je JavaBean, ktorý poskytuje abstrakciu okolo a java.util.concurrent.ThreadPoolExecutor inštanciu a vystavuje ju ako jar org.springframework.core.task.TaskExecutor. Ďalej je vysoko konfigurovateľný prostredníctvom vlastností servera corePoolSize, maxPoolSize, queueCapacity, allowCoreThreadTimeOut a keepAliveSeconds. V tomto výučbe sa pozrieme na corePoolSize a maxPoolSize vlastnosti.

2. corePoolSize vs. maxPoolSize

Používatelia noví v tejto abstrakcii môžu byť ľahko zmätení z rozdielu v týchto dvoch vlastnostiach konfigurácie. Pozrime sa preto na každú nezávisle.

2.1. corePoolSize

The corePoolSize je minimálny počet pracovníkov, ktorí musia zostať nažive bez časového limitu. Je to konfigurovateľná vlastnosť ThreadPoolTaskExecutor. Avšak ThreadPoolTaskExecutor delegáti abstrakcie nastavujú túto hodnotu na podkladovú java.util.concurrent.ThreadPoolExecutor. Pre objasnenie, všetkým vláknam môže vypršať časový limit - efektívne nastavenie hodnoty corePoolSize na nulu, ak sme nastavili allowCoreThreadTimeOut do pravda.

2.2. maxPoolSize

Naproti tomu maxPoolSize definuje maximálny počet vlákien, ktoré je možné vytvoriť. Podobne maxPoolSize majetok ThreadPoolTaskExecutor tiež deleguje svoju hodnotu na podkladové java.util.concurrent.ThreadPoolExecutor. Objasniť, maxPoolSize záleží na queueCapacity v tom ThreadPoolTaskExecutor vytvorí nové vlákno, iba ak počet položiek v jeho rade presiahne queueCapacity.

3. Aký je teda rozdiel?

Rozdiel medzi corePoolSize a maxPoolSize sa môže javiť ako evidentné. Existuje však niekoľko jemností týkajúcich sa ich správania.

Keď odovzdáme novú úlohu ThreadPoolTaskExecutor, vytvorí nové vlákno, ak je menšie ako corePoolSize vlákna bežia, aj keď sú v bazéne nečinné vlákna, alebo ak je menej ako maxPoolSize vlákna sú spustené a poradie definované queueCapacity je plný.

Ďalej sa pozrime na nejaký kód, aby sme videli príklady, keď každá vlastnosť začne pôsobiť.

4. Príklady

Po prvé, povedzme, že máme metódu, ktorá vykonáva nové vlákna, z ThreadPoolTaskExecutor, menovaný 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 () ;} catch (InterruptedException e) {Thread.currentThread (). interrupt ();}}); }}

Vyskúšajme predvolenú konfiguráciu ThreadPoolTaskExecutor, ktorý definuje a corePoolSize z jedného vlákna, neobmedzené maxPoolSize, a bez hraníc queueCapacity. Vo výsledku očakávame, že bez ohľadu na to, koľko úloh začneme, budeme mať spustené iba jedno vlákno:

@Test public void whenUsingDefaults_thenSingleThread () {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor (); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = nový CountDownLatch (10); this.startThreads (taskExecutor, countDownLatch, 10); while (countDownLatch.getCount ()> 0) {Assert.assertEquals (1, taskExecutor.getPoolSize ()); }}

Teraz poďme zmeniť corePoolSize na maximálne päť vlákien a zabezpečí, že sa bude správať tak, ako inzeruje. Vo výsledku očakávame spustenie piatich vlákien bez ohľadu na počet úloh zadaných do ThreadPoolTaskExecutor:

@Test public void whenCorePoolSizeFive_thenFiveThreads () {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor (); taskExecutor.setCorePoolSize (5); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = nový CountDownLatch (10); this.startThreads (taskExecutor, countDownLatch, 10); while (countDownLatch.getCount ()> 0) {Assert.assertEquals (5, taskExecutor.getPoolSize ()); }}

Podobne môžeme zvýšiť maxPoolSize do desiatich pri odchode z corePoolSize o piatej. Vo výsledku očakávame spustenie iba piatich vlákien. Pre objasnenie, iba päť vlákien začína, pretože queueCapacity je stále neobmedzený:

@Test public void whenCorePoolSizeFiveAndMaxPoolSizeTen_thenFiveThreads () {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor (); taskExecutor.setCorePoolSize (5); taskExecutor.setMaxPoolSize (10); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = nový CountDownLatch (10); this.startThreads (taskExecutor, countDownLatch, 10); while (countDownLatch.getCount ()> 0) {Assert.assertEquals (5, taskExecutor.getPoolSize ()); }}

Ďalej teraz zopakujeme predchádzajúci test, ale zvýšime hodnotu queueCapacity na desať a spustiť dvadsať vlákien. Preto teraz očakávame, že spustíme celkovo desať vlákien:

@Test public void whenCorePoolSizeFiveAndMaxPoolSizeTenAndQueueCapacityTen_thenTenThreads () {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor (); taskExecutor.setCorePoolSize (5); taskExecutor.setMaxPoolSize (10); taskExecutor.setQueueCapacity (10); taskExecutor.afterPropertiesSet (); CountDownLatch countDownLatch = nový CountDownLatch (20); this.startThreads (taskExecutor, countDownLatch, 20); while (countDownLatch.getCount ()> 0) {Assert.assertEquals (10, taskExecutor.getPoolSize ()); }}

Rovnako, ak by sme nastavili queueCapactity na nulu a začalo iba desať úloh, mali by sme tiež desať vlákien v našej ThreadPoolTaskExecutor.

5. Záver

ThreadPoolTaskExecutor je silná abstrakcia okolo a java.util.concurrent.ThreadPoolExecutor, poskytujúci možnosti konfigurácie corePoolSize, maxPoolSizea queueCapacity. V tomto návode sme sa pozreli na corePoolSize a maxPoolSize vlastnosti, ako aj ako maxPoolSize pracuje v tandeme s queueCapacity, čo nám umožňuje ľahko vytvárať oblasti vlákien pre akýkoľvek prípad použitia.

Ako vždy, kód nájdete na stránkach Github.


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