Programovanie

Ako virtuálny stroj Java vykonáva synchronizáciu vlákien

Všetky programy Java sú kompilované do súborov triedy, ktoré obsahujú bytecodes, čo je strojový jazyk virtuálneho stroja Java. Tento článok sa venuje tomu, ako sa so synchronizáciou vlákien zaobchádza pomocou virtuálneho stroja Java, vrátane príslušných bajtových kódov. (1 750 slov)

Tento mesiac Pod kapotou sa zameriava na synchronizáciu vlákien v jazyku Java aj vo virtuálnom stroji Java (JVM). Tento článok je posledným z dlhej série článkov o bytecode, ktoré som začal minulé leto. Opisuje iba dva operačné kódy priamo súvisiace so synchronizáciou vlákien, operačné kódy používané na vstup a výstup z monitorov.

Vlákna a zdieľané údaje

Jednou zo silných stránok programovacieho jazyka Java je jeho podpora multithreadingu na jazykovej úrovni. Veľká časť tejto podpory sa zameriava na koordináciu prístupu k údajom zdieľaným medzi viacerými vláknami.

JVM organizuje údaje spustenej aplikácie Java do niekoľkých runtime dátových oblastí: jedného alebo viacerých zásobníkov Java, haldy a oblasti metód. Informácie o pozadí týchto pamäťových oblastí nájdete v prvej Pod kapotou článok: „Štíhly, zlý virtuálny stroj.“

Vo vnútri virtuálneho stroja Java je každému vláknu pridelené a Zásobník Java, ktorý obsahuje údaje, ku ktorým nemá prístup žiadne iné vlákno, vrátane lokálnych premenných, parametrov a návratových hodnôt každej metódy, ktorú vlákno vyvolalo. Údaje v zásobníku sú obmedzené na primitívne typy a odkazy na objekty. V JVM nie je možné umiestniť obraz skutočného objektu do stohu. Všetky objekty sa nachádzajú na halde.

Je tu iba jeden halda vo vnútri JVM a zdieľajú ho všetky vlákna. Halda neobsahuje nič iné ako objekty. Neexistuje spôsob, ako umiestniť na haldu osamelý primitívny typ alebo referenciu na objekt - tieto veci musia byť súčasťou objektu. Polia sa nachádzajú na halde vrátane polí primitívnych typov, ale v Jave sú aj polia objekty.

Okrem Java stacku a haldy môžu byť v JVM ďalšie dáta, ktoré sa nachádzajú v oblasť metódy, ktorý obsahuje všetky triedne (alebo statické) premenné používané programom. Oblasť metódy je podobná zásobníku v tom, že obsahuje iba primitívne typy a odkazy na objekty. Na rozdiel od zásobníka sú však premenné triedy v oblasti metódy zdieľané všetkými vláknami.

Zámky objektov a tried

Ako je opísané vyššie, dve oblasti pamäte vo virtuálnom stroji Java obsahujú údaje zdieľané všetkými vláknami. Sú to:

  • Halda, ktorá obsahuje všetky objekty
  • Oblasť metódy, ktorá obsahuje všetky premenné triedy

Ak viac vlákien potrebuje používať rovnaké objekty alebo premenné triedy súčasne, musí byť ich prístup k údajom správne spravovaný. V opačnom prípade bude mať program nepredvídateľné správanie.

Na koordináciu zdieľaného prístupu k údajom medzi viacerými vláknami priradí virtuálny stroj Java a zámok s každým objektom a triedou. Zámok je ako privilégium, ktoré môže „vlastniť“ naraz iba jedno vlákno. Ak chce vlákno zamknúť konkrétny objekt alebo triedu, požiada JVM. V určitom okamihu potom, čo vlákno požiada JVM o zámok - možno veľmi skoro, možno neskôr, možno nikdy - JVM dá zámku vlákno. Keď vlákno už zámok nepotrebuje, vráti ho JVM. Ak iné vlákno požiadalo o rovnaký zámok, JVM odovzdá zámok tomuto vláknu.

Zámky triedy sa v skutočnosti implementujú ako zámky objektov. Keď JVM načíta súbor triedy, vytvorí inštanciu triedy java.lang.Class. Keď zamknete triedu, skutočne zamknete triedu tejto triedy Trieda objekt.

Vlákna nemusia získať zámok na prístup k premenným inštancií alebo tried. Ak vlákno získa zámok, žiadne iné vlákno nebude mať prístup k uzamknutým údajom, kým ho vlákno, ktoré zámok vlastní, neuvoľní.

Monitory

Spoločný podnik JVM používa zámky v spojení s monitory. Monitor je v zásade strážcom v tom, že dohliada na postupnosť kódu a zaisťuje, aby bol kód vykonávaný súčasne iba jedným vláknom.

Ku každému monitoru je priradený odkaz na objekt. Keď vlákno dorazí k prvej inštrukcii v bloku kódu, ktorý je pod dohľadom monitora, vlákno musí získať zámok na odkazovaný objekt. Vlákno nemá povolené vykonávať kód, kým nezíska zámok. Po získaní zámku vlákno vstúpi do bloku chráneného kódu.

Keď vlákno opustí blok, bez ohľadu na to, ako opustí blok, uvoľní zámok na pridruženom objekte.

Viaceré zámky

Jedno vlákno môže uzamknúť ten istý objekt viackrát. Pre každý objekt udržuje JVM počet, koľkokrát bol objekt uzamknutý. Odomknutý objekt má počet nula. Keď vlákno získa zámok prvýkrát, počet sa zvýši na jednu. Zakaždým, keď vlákno získa zámok na rovnakom objekte, počet sa zvýši. Zakaždým, keď vlákno uvoľní zámok, počet sa zníži. Keď počet dosiahne nulu, zámok sa uvoľní a sprístupní ostatným vláknam.

Synchronizované bloky

V terminológii jazykov Java sa nazýva koordinácia viacerých vlákien, ktoré musia mať prístup k zdieľaným údajom synchronizácia. Jazyk poskytuje dva vstavané spôsoby synchronizácie prístupu k údajom: pomocou synchronizovaných príkazov alebo synchronizovaných metód.

Synchronizované výkazy

Na vytvorenie synchronizovaného výpisu použite synchronizované kľúčové slovo s výrazom, ktorý sa vyhodnotí ako odkaz na objekt, ako v reverseOrder () nižšie uvedená metóda:

trieda KitchenSync {private int [] intArray = new int [10]; void reverseOrder () {synchronized (this) {int halfWay = intArray.length / 2; pre (int i = 0; i <halfWay; ++ i) {int upperIndex = intArray.length - 1 - i; int save = intArray [upperIndex]; intArray [upperIndex] = intArray [i]; intArray [i] = uložiť; }}}}

Vo vyššie uvedenom prípade sa príkazy obsiahnuté v synchronizovanom bloku nebudú vykonávať, kým sa nezíska zámok na aktuálnom objekte (toto). Ak namiesto a toto odkaz, výraz priniesol odkaz na iný objekt, zámok spojený s týmto objektom by sa získal skôr, ako vlákno bude pokračovať.

Dva kódy monitorovacie centrum a monitorexit, sa používajú na synchronizáciu blokov v rámci metód, ako je uvedené v nasledujúcej tabuľke.

Tabuľka 1. Monitory

Operačný kódOperand (y)Popis
monitorovacie centrumžiadnypop objectref, získa zámok spojený s objectref
monitorexitžiadnypop objectref, uvoľniť zámok spojený s objectref

Kedy monitorovacie centrum stretne virtuálny stroj Java, získava zámok pre objekt, na ktorý odkazuje stackref. Ak vlákno už vlastní zámok pre tento objekt, počet sa zvýši. Zakaždým monitorexit sa vykoná pre vlákno na objekte, počet sa zníži. Keď počet dosiahne nulu, monitor sa uvoľní.

Prezrite si sekvenciu bajtových kódov vygenerovanú kódom reverseOrder () metóda KitchenSync trieda.

Všimnite si, že klauzula catch zaisťuje, že uzamknutý objekt bude odomknutý, aj keď je v rámci synchronizovaného bloku vyvolaná výnimka. Bez ohľadu na to, ako je synchronizovaný blok ukončený, zámok objektu získaný pri vstupe vlákna do bloku bude definitívne uvoľnený.

Synchronizované metódy

Ak chcete synchronizovať celú metódu, stačí zahrnúť znak synchronizované kľúčové slovo ako jeden z kvalifikátorov metódy, ako napríklad v:

trieda HeatSync {private int [] intArray = new int [10]; synchronized void reverseOrder () {int halfWay = intArray.length / 2; pre (int i = 0; i <halfWay; ++ i) {int upperIndex = intArray.length - 1 - i; int save = intArray [upperIndex]; intArray [upperIndex] = intArray [i]; intArray [i] = uložiť; }}}

JVM nepoužíva žiadne špeciálne operačné kódy na vyvolanie alebo návrat zo synchronizovaných metód. Keď JVM vyrieši symbolický odkaz na metódu, určí, či je metóda synchronizovaná. Ak je, JVM získa zámok pred vyvolaním metódy. Pre inštančnú metódu získa JVM zámok spojený s objektom, na ktorý je metóda vyvolaná. Pre triednu metódu získava zámok spojený s triedou, do ktorej metóda patrí. Po dokončení synchronizovanej metódy, či už je dokončená vrátením alebo vyvolaním výnimky, sa zámok uvoľní.

Príde budúci mesiac

Teraz, keď som prešiel celou inštrukčnou sadou bytecode, rozšírim rozsah tohto stĺpca tak, aby zahŕňal rôzne aspekty alebo aplikácie technológie Java, nielen virtuálny stroj Java. Budúci mesiac začnem viacdielnu sériu, ktorá poskytne podrobný prehľad bezpečnostného modelu Java.

Bill Venners píše softvér profesionálne už 12 rokov. So sídlom v Silicon Valley poskytuje softvérové ​​poradenstvo a školiace služby pod menom Artima Software Company. V priebehu rokov vyvíjal softvér pre spotrebnú elektroniku, vzdelávanie, polovodiče a životné poistenie. Programoval v mnohých jazykoch na mnohých platformách: montážny jazyk na rôznych mikroprocesoroch, C na Unixe, C ++ na Windows, Java na webe. Je autorom knihy: Inside the Java Virtual Machine, ktorú vydalo vydavateľstvo McGraw-Hill.

Získajte viac informácií o tejto téme

  • Kniha Špecifikácia virtuálneho stroja Java (//www.aw.com/cp/lindholm-yellin.html), autormi Tim Lindholm a Frank Yellin (ISBN 0-201-63452-X), súčasť série Java Series (//www.aw.com/cp /javaseries.html), z Addison-Wesley, je definitívnym odkazom na virtuálny stroj Java.
  • Predchádzajúce články „Pod kapotou“:
  • „The Lean, Mean Virtual Machine“ predstavuje úvod do virtuálneho stroja Java.
  • „Životný štýl súboru triedy Java“ Poskytuje prehľad súboru triedy Java, formátu súboru, do ktorého sú kompilované všetky programy Java.
  • „Hromada zhromaždená v prostredí Java“ Poskytuje prehľad o zhromažďovaní odpadu všeobecne a predovšetkým v hromadách zhromaždených vo virtuálnom stroji Java.
  • „Základy Bytecode“ Predstavuje bajtkódy virtuálneho stroja Java a pojednáva predovšetkým o primitívnych typoch, konverzných operáciách a operáciách zásobníka.
  • „Floating Point Arithmetic“ Opisuje podporu pohyblivej rádovej čiarky virtuálneho stroja Java a bajtové kódy, ktoré vykonávajú operácie s pohyblivou rádovou čiarkou.
  • „Logic and Arithmetic“ Opisuje podporu virtuálneho stroja Java pre logickú a celočíselnú aritmetiku a súvisiace bajtové kódy.
  • „Objekty a polia“ Opisuje, ako virtuálny stroj Java pracuje s objektmi a poľami, a pojednáva o príslušných bajtových kódoch.
  • „Výnimky“ Opisuje, ako sa virtuálny stroj Java vyrovná s výnimkami, a popisuje príslušné bajtkódy.
  • „Try-Finally“ Popisuje, ako virtuálny stroj Java implementuje klauzuly „try-konečne“, a popisuje príslušné bajtkódy.
  • „Riadiaci tok“ Opisuje, ako virtuálny stroj Java implementuje riadiaci tok, a popisuje príslušné bajtkódy.
  • „The Architecture of Aglets“ Opisuje vnútorné fungovanie Agletov, technológie autonómneho softvérového agenta IBM založeného na prostredí Java.
  • „The Point of Aglets“ Analyzuje skutočnú užitočnosť mobilných agentov, ako je Aglets, technológia autonómneho softvérového agenta založeného na Jave od IBM.
  • „Vyvolanie a návrat metódy“ Vysvetľuje, ako virtuálny stroj Java vyvoláva a vracia sa z metód, vrátane príslušných bajtových kódov.

Tento príbeh „Ako virtuálny stroj Java vykonáva synchronizáciu vlákien“ pôvodne publikoval server JavaWorld.

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