Programarea reactiva in Java. Multithreading

Idea de programare reactiva a aparut relativ recent, acum in jur de 10 ani. In aceasta serie vom discuta despre programarea reactiva, avantajele sale precum si diferitele abordari si moduri in care poate sa fie utilizata.

Aug 24, 2021 120
De ce a devenit programarea reactiva atat de populara? La un moment dat, vitezele CPU au incetat sa mai creasca, astfel ca programatorii nu puteau sa se mai bazeze pe ele pentru creste viteza programelor. Era nevoie sa fie paralelizate.

CPU speed evolution.png


Poza de mai sus arata modul in care frecventa CPU a crescut in anii 90 si apoi a avut loc o crestere ridicata la inceputul anilor 2000. Din cate se pare, cam aici a fost limita.


De ce s-a oprit frecventa de crestere?

Microchip transistor sizes.png



Dimensiunile tranzistorilor din microcipuri si-au atins limitele. PN-junction a devenit pe cat de subtire s-a putut din punct de vedere fizic. Dupa cum putem vedea, in graficul de mai sus, marimea a scazut, in timp ce numarul tranzistorilor per microcip a inceput sa creasca.

O asemenea scalare a dus la cresterea frecventei. Pe masura ce electronii aproape ating viteza luminii, electronilor le ia mai putin timp sa parcurga intregul procesor datorita distantei mai mici. Insa tehnologia si-a atins limitele tehnologice. A trebuit sa apara altceva.


Multithreading

Si stim deja ce aparut: unitati de procesare multi-core. In loc sa ne bazam pe o performanta in continua crestere a CPU-ului, s-a decis cresterea numarului acestora. Dar utilizarea eficienta a procesoarelor multiple necesita multithreading.

Subiectul multithreading este foarte complex insa inevitabil in lumea noastra. Un computer tipic din ziua de azi are 4 sau mai multe cores si threads multiple. Un server modern si puternic ar putea sa aiba pana la 100 de cores. Daca nu implementezi multithreading in codul tau, nu poti obtine nici un fel de beneficii. Astfel ca, toate industriile globale se orienteaza pe acest trend.

Ca atare, apar si provocari. Este dificil sa programezi din cauza multithreading: sincronizare, races, debugging laborios, etc. Toate aceste aspecte au cauzat multe probleme pentru programatori. In afara de asta, costurile asociate cu acest tip de programare devin din ce in ce mai mari.

In Java, multithreading a aparut acum ceva timp; a fost folosit inca de la prima versiune.

Arata cam asa:

Multilthreading in Java.png


Scrierea de cod pentru un sistem complex folosind multithreading este o sarcina complicata. Nimeni nu mai procedeaza asa in ziua de azi. Este asemanator cu a programa in Assembler.

In multe cazuri, multithreading poate sa duca la scaderea performantei, nu la imbunatatirea ei.


Ce ar trebui sa facem?


parallel and asynchronous programming.png


In multe situatii, programarea paralela poate sa fie inlocuita cu programarea asincrona. Hai sa ne uitam la imaginea de mai sus. In poza din stanga, avem un copil care isi ajute mama. Copilul ia rufele din masina de spalat, i le da mamei si ea le pune in cos. Programul functioneaza asa, daca ar fi sa vorbim in thread-uri: threadul mama si threadul copil.

Teoretic, performanta ar trebui sa creasca in acest caz: doua persoane sunt mai bune decat una, si am folosit astfel doua cores. Dar imagineaza-ti o situatie din viata reala unde mama ii da rufele copilului si asteapta ca el sa le puna in masina de spalat. Sau copilul asteapta impreuna cu mama sa ca rufele sa se spele. De fapt, se impiedica unul pe celalalt. Mama ar face probabil toate aceste lucruri mai repede.

Ceva similar se intampla si in cadrul unui calculator. Astfel ca, abordarea paralelismului nu este atat de usoara precum am crede. Toate sincronizarile intre execution threads iau de fapt foarte mult timp.

In poza din dreapta, vedem un tanar care si-a cumparat o masina de spalat automata. In timp ce aceasta spala, el poate sa citeasca o carte. Astfel ca acesta se bucura de o activitate fara sa fie deranjat de rufe. In momentul in care rufele sunt spalate, va auzi un semnal si va reactiona. Exista, paralelism dar nu sincronizare. Asta inseamna ca nu se pierde timp cu sincronizarea, un beneficiu evident.

Aceast este o abordare asincrona. Avem un executor separat careia i-am atribuit propria sarcina, nu doar o parte din ea. In poza din stanga, mama si copilul fac o sarcina comuna. In poza din dreapta, masina de spalat si tanarul de langa ea au fiecare sarcina lor. La un anumit moment se vor intalni – cand masina de spalat isi termina programul si tanarul pune cartea deoparte. Dar pentru o ora si jumatate, sa zicem, a fost fericit. Nu i-a pasat de rufe, si-a citit cartea.


Articolul original poate sa fie citit aici.

Vrei sa inveti sa programezi cu Java sau sa iti imbunatatesti abilitatile de programare in Java? Parcurge cursurile noastre.

Daca iti place acest articol, distribuie-l si prietenilor tai!




Mai ai intrebari?
Contacteaza-ne.
Thank you.
Your request has been received.