ThreadPoolTaskExecutor corePoolSize u odnosu na maxPoolSize

1. Pregled

Proljeće ThreadPoolTaskExecutor je JavaBean koji pruža apstrakciju oko a java.util.concurrent.ThreadPoolExecutor instanci i izlaže je kao Proljeće org.springframework.core.task.TaskExecutor. Nadalje, vrlo je prilagodljiv svojstvima corePoolSize, maxPoolSize, queueCapacity, allowCoreThreadTimeOut i keepAliveSeconds. U ovom uputstvu pogledat ćemo corePoolSize i maxPoolSize Svojstva.

2. corePoolSize nasuprot maxPoolSize

Korisnici novi u ovoj apstrakciji mogu se lako zbuniti zbog razlike u dva svojstva konfiguracije. Stoga, pogledajmo svaku zasebno.

2.1. corePoolSize

The corePoolSize je minimalan broj radnika za održavanje bez vremenskog ograničenja. To je konfigurabilno svojstvo ThreadPoolTaskExecutor. Međutim ThreadPoolTaskExecutor delegati apstrakcije postavljajući ovu vrijednost na temeljnu java.util.concurrent.ThreadPoolExecutor. Da pojasnimo, sve niti mogu isteći - učinkovito postavljajući vrijednost corePoolSize na nulu ako smo postavili allowCoreThreadTimeOut do pravi.

2.2. maxPoolSize

Suprotno tome, maxPoolSize definira maksimalni broj niti koje se ikad mogu stvoriti. Slično tome, maxPoolSize vlasništvo ThreadPoolTaskExecutor također delegira njegovu vrijednost temeljnom java.util.concurrent.ThreadPoolExecutor. Razjasniti, maxPoolSize ovisi o queueCapacity u tome ThreadPoolTaskExecutor stvorit će novu nit samo ako broj stavki u njezinu redu premaši queueCapacity.

3. Pa u čemu je razlika?

Razlika između corePoolSize i maxPoolSize može izgledati evidentno. Međutim, postoje neke suptilnosti u vezi s njihovim ponašanjem.

Kada predajemo novi zadatak ThreadPoolTaskExeecuter, stvara novu nit ako je manje od corePoolSize niti se izvode, čak i ako u spremištu postoje neaktivne niti ili ako ih je manje od maxPoolSize niti se izvode, a red definiran s queueCapacity puno je.

Dalje, pogledajmo neki kod kako bismo vidjeli primjere kada svako svojstvo pokreće akciju.

4. Primjeri

Prvo, recimo da imamo metodu koja izvršava nove niti, iz ThreadPoolTaskExecutor, imenovan startThreads:

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

Isprobajmo zadanu konfiguraciju ThreadPoolTaskExecutor, koji definira a corePoolSize jedne niti, neograničena maxPoolSize, i neograničena queueCapacity. Kao rezultat, očekujemo da bez obzira na to koliko zadataka započnemo, imat ćemo pokrenut samo jednu nit:

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

Sada, izmijenimo corePoolSize na maksimalno pet niti i osigurajte da se ponaša onako kako je oglašeno. Kao rezultat, očekujemo pokretanje pet niti, bez obzira na broj zadataka predanih u ThreadPoolTaskExecutor:

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

Slično tome, možemo povećati maxPoolSize do deset dok napuštate corePoolSize u pet. Kao rezultat, očekujemo pokretanje samo pet niti. Da pojasnimo, započinje samo pet niti jer queueCapacity još uvijek neograničen:

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

Dalje, sada ćemo ponoviti prethodni test, ali povećati queueCapacity na deset i započnite dvadeset niti. Stoga sada očekujemo da ćemo započeti ukupno deset niti:

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

Isto tako, da smo postavili queueCapactity na nulu i započeli samo deset zadataka, imali bismo i deset niti ThreadPoolTaskExecutor.

5. Zaključak

ThreadPoolTaskExecutor je snažna apstrakcija oko a java.util.concurrent.ThreadPoolExecutor, pružajući mogućnosti za konfiguriranje corePoolSize, maxPoolSize, i queueCapacity. U ovom vodiču pogledali smo corePoolSize i maxPoolSize svojstva, kao i kako maxPoolSize radi u tandemu sa queueCapacity, omogućujući nam da lako stvorimo spremišta niti za bilo koji slučaj upotrebe.

Kao i uvijek, kod dostupan na Github-u.


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