Ohjelmointi

Kuinka Java-virtuaalikone suorittaa ketjun synkronoinnin

Kaikki Java-ohjelmat on koottu luokkatiedostoiksi, jotka sisältävät tavukoodeja, Java-virtuaalikoneen konekielen. Tässä artikkelissa tarkastellaan, miten Java-virtuaalikone käsittelee ketjun synkronoinnin, mukaan lukien asiaankuuluvat tavukoodit. (1750 sanaa)

Tämän kuukauden Konepellin alle tarkastelee ketjun synkronointia sekä Java-kielellä että Java-virtuaalikoneella (JVM). Tämä artikkeli on viimeinen viime kesänä aloittamani tavutekoodiartikkeleiden pitkä sarja. Siinä kuvataan vain kaksi opkoodia, jotka liittyvät suoraan langan synkronointiin, opkoodit, joita käytetään monitorien syöttämiseen ja poistumiseen.

Viestiketjut ja jaetut tiedot

Yksi Java-ohjelmointikielen vahvuuksista on sen tuki monisäikeisyydelle kielitasolla. Suuri osa tästä tuesta keskittyy useiden säikeiden kesken jaettujen tietojen käytön koordinointiin.

JVM järjestää käynnissä olevan Java-sovelluksen tiedot useisiin ajonaikaisiin tietoalueisiin: yhteen tai useampaan Java-pinoon, kasaan ja menetelmäalueeseen. Jos haluat tietoja näiden muistialueiden taustasta, katso ensimmäinen Konepellin alle artikkeli: "Laiha, keskimääräinen virtuaalikone."

Java-virtuaalikoneen sisällä jokaiselle säikeelle myönnetään a Java-pino, joka sisältää tietoja, joihin mikään muu ketju ei pääse, mukaan lukien paikalliset muuttujat, parametrit ja palautusarvot jokaisesta ketjun käyttämästä menetelmästä. Pinoa koskevat tiedot rajoittuvat primitiivisiin tyyppeihin ja objektiviittauksiin. JVM: ssä todellisen objektin kuvaa ei ole mahdollista sijoittaa pinoon. Kaikki esineet sijaitsevat kasalla.

On vain yksi ainoa pino JVM: n sisällä, ja kaikki ketjut jakavat sen. Kasa ei sisällä mitään muuta kuin esineitä. Ei ole mitään tapaa sijoittaa kasaan yksinäistä primitiivistä tyyppiä tai objektiviitettä - näiden asioiden on oltava osa esinettä. Matriisit sijaitsevat kasalla, mukaan lukien primitiiviset tyypit, mutta Java-taulukot myös objektit.

Java-pinon ja kasan lisäksi muut paikkatiedot voivat sijaita JVM: ssä on menetelmän alue, joka sisältää kaikki ohjelman käyttämät luokan (tai staattiset) muuttujat. Menetelmäalue on samanlainen kuin pino, koska se sisältää vain primitiivisiä tyyppejä ja objektiviittauksia. Toisin kuin pino, menetelmäalueella olevat luokan muuttujat jaetaan kaikille säikeille.

Objekti- ja luokan lukot

Kuten yllä on kuvattu, Java-virtuaalikoneen kahdella muistialueella on kaikkien säikeiden jakamia tietoja. Nämä ovat:

  • Kasa, joka sisältää kaikki esineet
  • Menetelmäalue, joka sisältää kaikki luokan muuttujat

Jos useiden ketjujen on käytettävä samoja objekteja tai luokan muuttujia samanaikaisesti, niiden pääsyä tietoihin on hallittava oikein. Muussa tapauksessa ohjelmalla on arvaamaton käyttäytyminen.

Jos haluat koordinoida jaetun datan käytön useiden säikeiden kesken, Java-virtuaalikone yhdistää a Lukko jokaisen objektin ja luokan kanssa. Lukko on kuin etuoikeus, jonka vain yksi lanka voi "hallita" kerralla. Jos ketju haluaa lukita tietyn objektin tai luokan, se kysyy JVM: ltä. Jossakin vaiheessa sen jälkeen, kun lanka pyytää JVM: ltä lukon - ehkä hyvin pian, ehkä myöhemmin, mahdollisesti koskaan - JVM antaa lukon langalle. Kun lanka ei enää tarvitse lukitusta, se palauttaa sen JVM: ään. Jos toinen lanka on pyytänyt samaa lukitusta, JVM siirtää lukituksen tälle langalle.

Luokan lukot toteutetaan tosiasiallisesti objektilukkoina. Kun JVM lataa luokkatiedoston, se luo luokan esiintymän java.lang.luokka. Kun lukitset luokan, sinä todella lukitset kyseisen luokan Luokka esine.

Lankojen ei tarvitse hankkia lukkoa esiintymien tai luokan muuttujien käyttämiseen. Jos lanka saa lukituksen, mikään muu lanka ei kuitenkaan pääse lukittuun dataan ennen kuin lukon omistava lanka vapauttaa sen.

Näytöt

JVM käyttää lukituksia yhdessä näytöt. Näyttö on pohjimmiltaan vartija, koska se valvoo koodisarjaa varmistaen, että vain yksi ketju kerrallaan suorittaa koodin.

Jokainen näyttö liittyy objektiviittaukseen. Kun lanka saapuu ensimmäiseen käskyyn koodilohkossa, joka on monitorin valvovan silmän alla, langan on hankittava lukitus viitattuun objektiin. Lanka ei saa suorittaa koodia, ennen kuin se saa lukituksen. Saatuaan lukituksen lanka siirtyy suojatun koodin lohkoon.

Kun säie lähtee lohkosta, riippumatta siitä, kuinka se poistuu lohkosta, se vapauttaa siihen liittyvän objektin lukon.

Useita lukkoja

Yksi lanka saa lukita saman objektin useita kertoja. Kunkin objektin kohdalla JVM ylläpitää lukua siitä, kuinka monta kertaa objekti on lukittu. Lukitsemattoman objektin lukumäärä on nolla. Kun lanka hankkii lukituksen ensimmäisen kerran, laskenta kasvaa yhteen. Joka kerta, kun lanka hankkii lukituksen samalle kohteelle, määrää lisätään. Joka kerta, kun lanka vapauttaa lukon, määrää vähennetään. Kun määrä saavuttaa nollan, lukitus vapautetaan ja asetetaan muiden säikeiden saataville.

Synkronoidut lohkot

Java-kielen terminologiassa kutsutaan useiden säikeiden koordinointia, joiden on käytettävä jaettua dataa synkronointi. Kieli tarjoaa kaksi sisäänrakennettua tapaa synkronoida pääsy tietoihin: synkronoiduilla lausekkeilla tai synkronoiduilla menetelmillä.

Synkronoidut lauseet

Voit luoda synkronoidun käskyn käyttämällä synkronoitu avainsana lausekkeella, joka arvioi objektiviittauksen, kuten käänteinen järjestys() alla oleva menetelmä:

luokka KitchenSync {private int [] intArray = new int [10]; void reverseOrder () {synkronoitu (tämä) {int halfWay = intArray.length / 2; for (int i = 0; i <puolitie; ++ i) {int upperIndex = intArray.pituus - 1 - i; int tallenna = intArray [upperIndex]; intArray [upperIndex] = intArray [i]; intArray [i] = tallenna; }}}}

Edellä esitetyssä tapauksessa synkronoidun lohkon sisältämät lauseet suoritetaan vasta, kun nykyiselle objektille on hankittu lukitus (Tämä). Jos a Tämä viittaus, lauseke antoi viittauksen toiseen objektiin, kyseiseen objektiin liittyvä lukko hankitaan ennen säiettä jatkamista.

Kaksi opcodia, monitorenter ja monitorexit, käytetään menetelmien synkronointilohkoihin, kuten alla olevassa taulukossa on esitetty.

Taulukko 1. Näytöt

OpcodeOperandi (t)Kuvaus
monitorenterei mitäänpop objectref, hanki objectrefiin liittyvä lukko
monitorexitei mitäänpop objectref, vapauta objectrefiin liittyvä lukko

Kun monitorenter Java-virtuaalikone kohtaa sen, se hankkii lukon objektille, johon pino objectref viittaa. Jos lanka omistaa jo kyseisen objektin lukituksen, laskenta kasvaa. Joka kerta monitorexit suoritetaan objektin säikeelle, määrää vähennetään. Kun määrä saavuttaa nollan, näyttö vapautetaan.

Katsokaa käänteinen järjestys() menetelmä KitchenSync luokassa.

Huomaa, että lukituslauseke varmistaa, että lukitun kohteen lukitus avataan, vaikka synkronoidun lohkon sisällä heitetäänkin poikkeus. Huolimatta siitä, miten synkronoidusta lohkosta poistutaan, objektilukko, joka on saatu, kun säie tuli lohkoon, vapautetaan.

Synkronoidut menetelmät

Voit synkronoida koko menetelmän lisäämällä vain synkronoitu avainsana yhtenä menetelmämääritelmistä, kuten:

luokka HeatSync {yksityinen int [] intArray = uusi int [10]; synkronoitu void reverseOrder () {int halfWay = intArray.length / 2; for (int i = 0; i <puolitie; ++ i) {int upperIndex = intArray.pituus - 1 - i; int tallenna = intArray [upperIndex]; intArray [upperIndex] = intArray [i]; intArray [i] = tallenna; }}}

JVM ei käytä mitään erityisiä opcodeja synkronoitujen menetelmien kutsumiseen tai palaamiseen. Kun JVM ratkaisee symbolisen viittauksen menetelmään, se määrittää, onko menetelmä synkronoitu. Jos on, JVM hankkii lukituksen ennen menetelmän käyttämistä. Ilmentymämenetelmää varten JVM hankkii lukon, joka liittyy kohteeseen, johon menetelmää käytetään. Luokkamenetelmälle se hankkii lukon, joka liittyy luokkaan, johon menetelmä kuuluu. Kun synkronoitu menetelmä on suoritettu loppuun, riippumatta siitä, onko se valmis palaamalla tai heittämällä poikkeuksen, lukko vapautetaan.

Tulossa ensi kuussa

Nyt kun olen käynyt läpi koko tavukoodikäskyjoukon, laajennan tämän sarakkeen soveltamisalaa kattamaan Java-tekniikan eri näkökohdat tai sovellukset, ei pelkästään Java-virtuaalikone. Ensi kuussa aloitan moniosaisen sarjan, joka antaa perusteellisen yleiskuvan Java-suojausmallista.

Bill Venners on kirjoittanut ohjelmistoja ammattimaisesti 12 vuotta. Piilaaksossa toimiva hän tarjoaa ohjelmistokonsultointi- ja koulutuspalveluja nimellä Artima Software Company. Vuosien varrella hän on kehittänyt ohjelmistoja kulutuselektroniikka-, koulutus-, puolijohde- ja henkivakuutusteollisuudelle. Hän on ohjelmoinut monilla kielillä monilla alustoilla: kokoonpanokieli useille mikroprosessoreille, C Unixille, C ++ Windowsille, Java Webissä. Hän on kirjoittanut kirjan: Inside the Java Virtual Machine, julkaisija McGraw-Hill.

Lisätietoja tästä aiheesta

  • Kirja Java-virtuaalikoneen määrittely (//www.aw.com/cp/lindholm-yellin.html), kirjoittaneet Tim Lindholm ja Frank Yellin (ISBN 0-201-63452-X), osa Java-sarjaa (//www.aw.com/cp /javaseries.html), Addison-Wesley, on lopullinen Java-virtuaalikoneen viite.
  • Edelliset "Hupun alla" -artikkelit:
  • "Lean, Mean Virtual Machine" - Johdanto Java-virtuaalikoneeseen.
  • "Java Class File Lifestyle" antaa yleiskuvan Java-luokan tiedostosta, tiedostomuodosta, johon kaikki Java-ohjelmat kootaan.
  • "Java's Garbage-Collected Heap" Antaa yleiskuvan roskien keräyksestä yleensä ja erityisesti Java-virtuaalikoneen roskikorista.
  • "Bytecode Basics" esittelee Java-virtuaalikoneen tavukoodit ja käsittelee erityisesti primitiivisiä tyyppejä, muunnosoperaatioita ja pinooperaatioita.
  • "Floating Point Arithmetic" kuvaa Java-virtuaalikoneen liukulukutukea ja liukulukutoimintoja suorittavia tavukoodeja.
  • "Logiikka ja aritmeettinen" Kuvailee Java-virtuaalikoneen tukea loogiselle ja kokonaislukutaidolle sekä niihin liittyvät tavukoodit.
  • "Objektit ja taulukot" Kuvailee, kuinka Java-virtuaalikone käsittelee objekteja ja taulukoita, ja keskustelee asiaankuuluvista tavakoodeista.
  • "Poikkeukset" kuvaa, kuinka Java-virtuaalikone käsittelee poikkeuksia, ja keskustelee asiaankuuluvista tavukoodeista.
  • "Kokeile lopulta" kuvaa, kuinka Java-virtuaalikone toteuttaa kokeilulausekkeet, ja keskustelee asiaankuuluvista tavukoodeista.
  • "Ohjausvirta" kuvaa, kuinka Java-virtuaalikone toteuttaa ohjausvirtauksen, ja keskustelee asiaankuuluvista tavukoodeista.
  • "Agletsin arkkitehtuuri" kuvaa IBM: n autonomisen Java-pohjaisen ohjelmistoagenttitekniikan, Agletsin sisäisen toiminnan.
  • "Point of Aglets" analysoi mobiiliagenttien, kuten Agletsin, IBM: n autonomisen Java-pohjaisen ohjelmistoagenttiteknologian, todellisen hyödyllisyyden.
  • "Menetelmän kutsuminen ja palautus" Selittää, kuinka Java-virtuaalikone kutsuu ja palaa menetelmistä, mukaan lukien asiaankuuluvat tavukoodit.

Tämän tarinan "Kuinka Java-virtuaalikone suorittaa langansynkronoinnin" julkaisi alun perin JavaWorld.

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