Modellek menete Java-ban

1. Bemutatkozás

Alkalmazásainkban gyakran több dolgot is képesek vagyunk elvégezni egyszerre. Ezt többféleképpen is elérhetjük, de kulcsfontosságú közülük a multitasking valamilyen formában történő megvalósítása.

A többfeladatos feladat több feladat egyidejű futtatását jelenti, ahol minden feladat elvégzi a munkáját. Ezek a feladatok általában egyszerre futnak, ugyanazon memóriát olvassák és írják, és ugyanazokkal az erőforrásokkal működnek együtt, de különböző dolgokat végeznek.

2. Natív szálak

A Java-ban a többfeladatos feladatok végrehajtásának szokásos módja a szálak használata. A szálkezelést általában az operációs rendszerig támogatják. Az ezen a szinten működő szálakat „natív szálaknak” nevezzük.

Az operációs rendszernek van néhány olyan képessége a szálkezeléssel kapcsolatban, amelyek gyakran nem érhetők el alkalmazásaink számára, egyszerűen azért, mert sokkal közelebb van az alapul szolgáló hardverhez. Ez azt jelenti, hogy a natív szálak futtatása általában hatékonyabb. Ezek a szálak közvetlenül a számítógép CPU-jának végrehajtási szálaihoz kapcsolódnak - és az operációs rendszer kezeli a szálak hozzárendelését a CPU magjaihoz.

A Java összes JVM nyelvét lefedő normál szálmodellje natív szálakat használ. Ez a Java 1.2 óta van így, függetlenül attól az alaprendszertől, amelyen a JVM fut.

Ez azt jelenti, hogy bármikor használjuk a Java szálainak bármelyikét, akkor natív szálakat használunk. Ebbe beletartozik java.lang.Thread, java.util.concurrent.Executor, java.util.concurrent.ExecutorService, stb.

3. Zöld szálak

A szoftverfejlesztésben, a natív szálak egyik alternatívája a zöld szálak. Itt használunk szálakat, de ezek nem közvetlenül kapcsolódnak az operációs rendszer szálaihoz. Ehelyett az alapul szolgáló architektúra maga kezeli a szálakat, és kezeli, hogy ezek hogyan kapcsolódnak az operációs rendszer szálaihoz.

Általában ez úgy működik, hogy több natív szálat futtat, majd a zöld szálakat lefoglalja ezekre a natív szálakra végrehajtás céljából. Ezután a rendszer kiválaszthatja, hogy az adott pillanatban melyik zöld szál aktív, és melyik natív szálon aktív.

Ez nagyon bonyolultnak hangzik, és az is. De ez egy bonyodalom, amellyel általában nem kell törődnünk. Az alapul szolgáló architektúra gondoskodik minderről, és úgy kell használni, mintha natív szálmodell lenne.

Akkor miért tennénk ezt? A natív szálak futtatása nagyon hatékony, de az indításuk és leállításuk magas költségekkel jár. A zöld szálak segítenek elkerülni ezeket a költségeket, és sokkal nagyobb rugalmasságot adnak az architektúrának. Ha viszonylag hosszú futású szálakat használunk, akkor a natív szálak nagyon hatékonyak. A nagyon rövid életű munkák esetében az indulásuk költségei meghaladhatják a használatuk előnyeit. Ezekben az esetekben a zöld szálak hatékonyabbá válhatnak.

Sajnálatos módon, A Java nem rendelkezik beépített támogatással a zöld szálakhoz.

A nagyon korai verziók normál szálmodellként natív szálak helyett zöld szálakat használtak. Ez megváltozott a Java 1.2-ben, és azóta sem támogatott a JVM.

Kihívást jelent a zöld szálak megvalósítása a könyvtárakban is, mert a jó teljesítményhez nagyon alacsony szintű támogatásra lenne szükségük. Mint ilyen, gyakran alkalmazott alternatíva a szál.

4. Rostok

A szálak a szálak alternatív formái, és hasonlóak a zöld szálakhoz. Mindkét esetben nem natív szálakat használunk, hanem a mögöttes rendszervezérlőket használjuk, amelyek bármikor futnak. A zöld szálak és a szálak közötti nagy különbség a kontroll szintjén van, és konkrétan abban, hogy ki irányítja.

A zöld szálak a megelőző multitasking egyik formája. Ez azt jelenti, hogy az alapul szolgáló architektúra teljes mértékben felelős annak eldöntéséért, hogy melyik szálat hajtják végre egy adott időpontban.

Ez azt jelenti, hogy a szálak összes szokásos kérdése érvényes, ahol nem tudunk semmit a szálak végrehajtásának sorrendjéről, illetve arról, hogy melyikeket hajtják végre egyszerre. Ez azt is jelenti, hogy az alapul szolgáló rendszernek bármikor képesnek kell lennie a kódunk szüneteltetésére és újraindítására, egy módszer vagy akár egy utasítás közepén.

A rostok egyfajta kooperatív multitasking formát jelentenek, vagyis egy futó szál addig fog futni, amíg jelzi, hogy engedhet egy másiknak. Ez azt jelenti, hogy felelősségünk, hogy a szálak együttműködjenek egymással. Ez közvetlen irányítást biztosít számunkra, amikor a szálak szüneteltethetik a végrehajtást, ahelyett, hogy a rendszer ezt nekünk döntené.

Ez azt is jelenti, hogy a kódunkat oly módon kell megírnunk, amely ezt lehetővé teszi. Különben nem fog menni. Ha kódunknak nincsenek megszakítási pontjai, akkor előfordulhat, hogy egyáltalán nem használunk szálakat.

A Java jelenleg nem rendelkezik beépített támogatással a szálakhoz. Vannak olyan könyvtárak, amelyek ezt be tudják vezetni az alkalmazásainkba, többek között:

4.1. kvazár

A Quasar egy Java könyvtár, amely jól működik a tiszta Java-val és a Kotlin-nal, és rendelkezik egy alternatív verzióval, amely a Clojure-mal is működik.

Úgy működik, hogy van egy Java ügynöke, amelynek az alkalmazás mellett kell futtatnia, és ez az ügynök felelős a szálak kezeléséért és azok megfelelő működésének biztosításáért. A Java ügynök használata azt jelenti, hogy nincs szükség speciális építési lépésekre.

A Quasar a Java 11 megfelelő működéséhez is szükséges, ami korlátozhatja az azt használó alkalmazásokat. A régebbi verziók használhatók a Java 8 rendszeren, de ezeket nem támogatják aktívan.

4.2. Kilim

A Kilim egy Java könyvtár, amely nagyon hasonló funkcionalitást kínál, mint a Quasar, de ezt a bytec szövéssel Java ügynök helyett használja. Ez azt jelenti, hogy több helyen is képes működni, de bonyolultabbá teszi az összeállítási folyamatot.

A Kilim a Java 7-es és újabb verziókkal működik, és helyesen fog működni még olyan esetekben is, amikor a Java ügynök nem választható. Például, ha már mást használnak műszerezéshez vagy monitorozáshoz.

4.3. Projekt Loom

A Project Loom az OpenJDK projekt kísérlete, hogy rostokat adjon magához a JVM-hez, nem pedig kiegészítő könyvtárként. Ez megadja nekünk a szálak előnyeit a szálakkal szemben. Azáltal, hogy közvetlenül a JVM-en hajtja végre, segíthet elkerülni azokat a bonyodalmakat, amelyeket a Java ügynökök és a bytecode szövés okoz.

A Project Loomnak nincs jelenlegi kiadási ütemezése, de a korai hozzáférésű bináris fájlokat jelenleg le tudjuk tölteni, hogy lássuk, hogyan mennek a dolgok. Mivel azonban még nagyon korai a helyzet, körültekintően kell erre támaszkodnunk bármilyen gyártási kód esetében.

5. Társprogramok

A társprogramok a menetek és a szálak alternatívái. A társprogramokat mint rostokat gondolhatjuk ütemezés bármilyen formája nélkül. Ahelyett, hogy az alapul szolgáló rendszer bármikor eldöntené, hogy mely feladatokat hajtják végre, a kódunk ezt közvetlenül elvégzi.

Általánosságban úgy írunk társprogramokat, hogy azok áramlásuk meghatározott pontjain adódjanak. Ezeket szünetpontként tekinthetjük a funkciónkban, ahol ez leáll és potenciálisan közbenső eredményt ad ki. Ha engedünk, akkor leállítanak minket, amíg a hívó kód bármilyen okból úgy dönt, hogy újraindít minket. Ez azt jelenti, hogy hívó kódunk vezérli annak ütemezését, hogy ez mikor fog futni.

Kotlin natív támogatást nyújt a szokásos könyvtárba beépített társprogramokhoz. Számos másik Java könyvtár létezik, amelyeket igény szerint megvalósíthatunk is.

6. Következtetés

Számos különböző alternatívát láthattunk kódunkban a többfeladatos feladatok elvégzéséhez, a hagyományos natív szálaktól a nagyon könnyű alternatívákig. Miért ne próbálja ki őket legközelebb, amikor egy alkalmazásnak párhuzamosságra van szüksége?


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