Programavimas

Kaip „Java“ virtuali mašina atlieka siūlų sinchronizavimą

Visos „Java“ programos yra sukompiliuotos į klasės failus, kuriuose yra baitų kodai, „Java“ virtualiosios mašinos mašininė kalba. Šiame straipsnyje apžvelgiama, kaip „Java“ virtuali mašina tvarko siūlų sinchronizavimą, įskaitant atitinkamus baitų kodus. (1750 žodžių)

Šio mėnesio Po gaubtu nagrinėja siūlų sinchronizavimą „Java“ kalba ir „Java“ virtualia mašina (JVM). Šis straipsnis yra paskutinis iš ilgų bytecode straipsnių, kuriuos pradėjau praėjusią vasarą, serijos. Jame aprašomi tik du opcodai, tiesiogiai susiję su gijų sinchronizavimu, opcodes, naudojami įeinant ir išeinant iš monitorių.

Siūlai ir bendri duomenys

Viena iš „Java“ programavimo kalbos stipriųjų pusių yra palaikymas daugialypiam gijimui kalbos lygiu. Didžioji šios paramos dalis yra prieigos prie duomenų, bendrinamų tarp kelių gijų, koordinavimas.

JVM organizuoja veikiančios „Java“ programos duomenis į keletą vykdymo laiko duomenų sričių: vieną ar daugiau „Java“ paketų, kaupo ir metodo sritį. Jei norite sužinoti apie šias atminties sritis, žr. Pirmąjį Po gaubtu straipsnis: „Liekna, vidutinė virtuali mašina“.

„Java“ virtualios mašinos viduje kiekvienai gijai suteikiama a „Java“ kaminas, kuriame yra duomenys, kurių negali pasiekti jokia kita gija, įskaitant kiekvieno metodo, kurio buvo naudojamas, vietinius kintamuosius, parametrus ir grąžinimo vertes. Duomenys rietuvėje apsiriboja primityviais tipais ir objektų nuorodomis. JVM negalima įdėti faktinio objekto atvaizdo į rietuvę. Visi daiktai yra ant krūvos.

Yra tik vienas krūva JVM viduje, ir visos gijos juo dalijasi. Krūvoje nėra nieko, išskyrus daiktus. Jokiu būdu negalima ant krūvos uždėti vienatvės primityvaus tipo ar objekto nuorodos - šie dalykai turi būti objekto dalis. Masyvai yra ant krūvos, įskaitant primityvių tipų masyvus, tačiau „Java“ masyvai taip pat yra objektai.

Be „Java“ kamino ir kaupo, kiti vietos duomenys gali būti JVM metodo sritis, kuriame yra visi programos naudojami statiniai (arba statiniai) kintamieji. Metodo sritis yra panaši į kaminą, nes joje yra tik primityvūs tipai ir objektų nuorodos. Skirtingai nei kamino, metodo srityje esančių klasių kintamuosius dalijasi visos gijos.

Objekto ir klasės spynos

Kaip aprašyta aukščiau, dviejose „Java“ virtualiosios mašinos atminties srityse yra visų gijų bendrų duomenų. Šitie yra:

  • Krūva, kurioje yra visi daiktai
  • Metodo sritis, kurioje yra visi klasės kintamieji

Jei kelioms gijoms reikia tuo pačiu metu naudoti tuos pačius objektus ar klasės kintamuosius, jų prieiga prie duomenų turi būti tinkamai valdoma. Priešingu atveju programa elgsis nenuspėjamai.

Norėdami suderinti bendrą prieigą prie duomenų tarp kelių gijų, „Java“ virtualioji mašina susieja a užraktas su kiekvienu objektu ir klase. Užraktas yra tarsi privilegija, kurią vienu metu gali „turėti“ tik viena gija. Jei gija nori užrakinti tam tikrą objektą ar klasę, ji klausia JVM. Tam tikru momentu po to, kai siūlas paprašo JVM užrakto - galbūt labai greitai, gal vėliau, galbūt niekada - JVM suteikia užraktą siūlui. Kai siūlui nebereikia užrakto, jis grąžina jį JVM. Jei kitas siūlas paprašė to paties užrakto, JVM perduoda užraktą šiai gijai.

Klasių spynos iš tikrųjų įgyvendinamos kaip objektų spynos. Kai JVM įkelia klasės failą, jis sukuria klasės egzempliorių java.lang.Klasė. Užrakindami klasę, jūs iš tikrųjų užrakinate tos klasės Klasė objektas.

Siūlai nereikia užrakinti prieigos prie egzempliorių ar klasės kintamųjų. Tačiau jei gija gauna užraktą, jokia kita gija negali pasiekti užrakintų duomenų, kol gija, kuriai priklauso užraktas, juos atleis.

Monitoriai

JVM užraktus naudoja kartu su monitoriai. Monitorius iš esmės yra globėjas, nes jis stebi kodo seką, užtikrindamas, kad kodą vykdytų tik viena gija vienu metu.

Kiekvienas monitorius susietas su objekto nuoroda. Kai gija ateina į pirmąją instrukciją kodo bloke, kuris yra budriai stebint monitoriui, siūlas turi užblokuoti nurodytą objektą. Siūlai neleidžiama vykdyti kodo, kol jis negauna užrakto. Gavęs užraktą, siūlas patenka į saugomo kodo bloką.

Kai siūlas palieka bloką, nesvarbu, kaip jis palieka bloką, jis atleidžia susijusio objekto užraktą.

Keli užraktai

Vienai gijai leidžiama tą patį objektą užrakinti kelis kartus. Kiekvienam objektui JVM skaičiuoja, kiek kartų objektas buvo užrakintas. Atrakinto objekto skaičius yra lygus nuliui. Kai siūlas pirmą kartą įgyja užraktą, skaičius padidinamas iki vieno. Kiekvieną kartą, kai gija įgyja to paties objekto užraktą, skaičius yra padidinamas. Kiekvieną kartą, kai siūlas atleidžia užraktą, skaičius mažinamas. Kai skaičius pasiekia nulį, užraktas atleidžiamas ir tampa prieinamas kitoms gijoms.

Sinchronizuoti blokai

„Java“ kalbos terminologijoje vadinamas kelių gijų, turinčių prieigą prie bendrinamų duomenų, koordinavimas sinchronizavimas. Kalba pateikia du integruotus prieigos prie duomenų sinchronizavimo būdus: sinchronizuotais teiginiais arba sinchronizuotais metodais.

Sinchronizuoti teiginiai

Norėdami sukurti sinchronizuotą pareiškimą, naudokite sinchronizuotas raktinis žodis su išraiška, vertinančia objekto nuorodą, kaip Atvirkštinė tvarka() metodas:

klasė „KitchenSync“ {private int [] intArray = new int [10]; void reverseOrder () {sinchronizuotas (tai) {int halfWay = intArray.length / 2; už (int i = 0; i <halfWay; ++ i) {int upperIndex = intArray.length - 1 - i; int išsaugoti = intArray [upperIndex]; intArray [viršutinėIndex] = intArray [i]; intArray [i] = išsaugoti; }}}}

Aukščiau nurodytu atveju sakiniai, esantys sinchronizuotame bloke, nebus vykdomi tol, kol nebus užblokuotas dabartinis objektas (tai). Jei vietoj a tai nuoroda, išraiška suteikė nuorodą į kitą objektą, užraktas, susietas su tuo objektu, bus įgytas prieš tęsiant giją.

Du opcodes, monitorenter ir monitoreksitas, naudojami sinchronizavimo blokams pagal metodus, kaip parodyta toliau pateiktoje lentelėje.

1 lentelė. Monitoriai

„Opcode“Operandas (-ai)apibūdinimas
monitorenternė vienaspop objectref, įsigykite užraktą, susietą su objectref
monitoreksitasnė vienaspop objectref, atleiskite užraktą, susijusį su objectref

Kada monitorenter susiduria su „Java“ virtualia mašina, ji įgyja objekto, kuriam „stackre“ nurodo objektą, užraktą. Jei gijai jau priklauso to objekto užraktas, skaičius yra padidinamas. Kiekvieną kartą monitoreksitas yra vykdomas objekto gijai, skaičius mažinamas. Kai skaičius pasiekia nulį, monitorius atleidžiamas.

Pažvelkite į bytecode seką, sukurtą Atvirkštinė tvarka() metodas „KitchenSync“ klasė.

Atminkite, kad gaudymo sąlyga užtikrina, kad užrakintas objektas bus atrakintas, net jei išimtis išmetama iš sinchronizuoto bloko. Nesvarbu, kaip išeinama iš sinchronizuoto bloko, objekto užraktas, įgytas, kai gija tikrai įeina į bloką, bus paleista.

Sinchronizuoti metodai

Norėdami sinchronizuoti visą metodą, tiesiog įtraukite sinchronizuotas raktinis žodis kaip vienas iš metodo kvalifikatorių, kaip aprašyta:

klasė „HeatSync“ {privatus int [] intArray = naujas int [10]; sinchronizuotas negaliojantis reverseOrder () {int halfWay = intArray.length / 2; už (int i = 0; i <halfWay; ++ i) {int upperIndex = intArray.length - 1 - i; int išsaugoti = intArray [upperIndex]; intArray [viršutinėIndex] = intArray [i]; intArray [i] = išsaugoti; }}}

JVM nenaudoja jokių specialių opkodų, kad iškviestų arba grįžtų iš sinchronizuotų metodų. Kai JVM išsprendžia simbolinę nuorodą į metodą, jis nustato, ar metodas yra sinchronizuotas. Jei taip, prieš pradėdamas metodą JVM įsigyja užraktą. Atvejų metodo atveju JVM įgyja užraktą, susietą su objektu, kuriam taikomas metodas. Taikant klasės metodą, jis įgyja spyną, susietą su klase, kuriai priklauso metodas. Užbaigus sinchronizuotą metodą, nesvarbu, ar jis baigiamas grįžus, ar išmetus išimtį, užraktas atleidžiamas.

Ateis kitą mėnesį

Dabar, kai perėjau visą baitų kodų instrukcijų rinkinį, išplėsiu šio stulpelio taikymo sritį, įtraukdama įvairius „Java“ technologijos aspektus ar programas, ne tik „Java“ virtualioji mašina. Kitą mėnesį aš pradėsiu kelių dalių seriją, kurioje išsamiai apžvelgiama „Java“ saugos modelis.

Billas Vennersas profesionaliai rašė programinę įrangą 12 metų. Silicio slėnyje įsikūręs jis teikia programinės įrangos konsultavimo ir mokymo paslaugas „Artima Software Company“ vardu. Per daugelį metų jis sukūrė programinę įrangą buitinės elektronikos, švietimo, puslaidininkių ir gyvybės draudimo pramonei. Jis programavo daugeliu kalbų daugelyje platformų: surinkimo kalba įvairiuose mikroprocesoriuose, C „Unix“, C ++ „Windows“, „Java“ internete. Jis yra knygos „Inside the Java Virtual Machine“, kurią išleido McGraw-Hill, autorius.

Sužinokite daugiau apie šią temą

  • Knyga „Java“ virtualiosios mašinos specifikacija (//www.aw.com/cp/lindholm-yellin.html), autoriai Tim Lindholm ir Frank Yellin (ISBN 0-201-63452-X), „Java“ serijos dalis (//www.aw.com/cp /javaseries.html) iš Addison-Wesley yra galutinė „Java“ virtualiosios mašinos nuoroda.
  • Ankstesni straipsniai „Po gaubtu“:
  • „Lean, Mean Virtual Machine“ - tai „Java“ virtualiosios mašinos įvadas.
  • „Java klasės failų gyvenimo būdas“ pateikia „Java“ klasės failo, failo formato, į kurį sudaromos visos „Java“ programos, apžvalgą.
  • „Java's Garbage-Collected Heap“ Apžvelgia šiukšlių surinkimą apskritai ir ypač apie „Java“ virtualiosios mašinos šiukšlių surinktą kaupą.
  • „Bytecode Basics“ pristato „Java“ virtualiosios mašinos baitų kodus ir ypač aptaria primityvius tipus, konvertavimo operacijas ir kamino operacijas.
  • „Kintamojo taško aritmetika“ apibūdina „Java“ virtualiosios mašinos slankiojo kablelio palaikymą ir baitekodus, kurie atlieka slankiojo kablelio operacijas.
  • „Logika ir aritmetika“ Apibūdina „Java“ virtualiosios mašinos palaikymą loginei ir sveikojo skaičiaus aritmetikai bei susijusius baitų kodus.
  • „Objektai ir masyvai“ Aprašoma, kaip „Java“ virtualioji mašina elgiasi su objektais ir masyvais, ir aptaria atitinkamus baitų kodus.
  • „Išimtys“ Aprašoma, kaip „Java“ virtuali mašina tvarko išimtis, ir aptariami atitinkami baitų kodai.
  • „Pabandykite pagaliau“ Aprašoma, kaip „Java“ virtualioji mašina įgyvendina bandymo galutinis išlygas, ir aptaria atitinkamus baitų kodus.
  • „Valdymo srautas“ Aprašoma, kaip „Java“ virtuali mašina įgyvendina valdymo srautą, ir aptaria atitinkamus baitų kodus.
  • „Aglets architektūra“ apibūdina „Aglets“, IBM autonominės „Java“ pagrindu sukurtos programinės įrangos agento technologijos, vidinį darbą.
  • „Aglets taškas“ analizuoja realių mobiliųjų agentų, tokių kaip „Aglets“, IBM autonominės „Java“ pagrindu sukurtos programinės įrangos agentų technologijos, naudingumą.
  • „Metodo iškvietimas ir grąžinimas“ Paaiškina, kaip „Java“ virtualioji mašina iškviečia ir grįžta iš metodų, įskaitant atitinkamus baitų kodus.

Šią istoriją „Kaip„ Java “virtualioji mašina atlieka siūlų sinchronizavimą“ iš pradžių paskelbė „JavaWorld“.