"Hei, Amigo!"
"Hei, Ellie!"
"Jeg vil fortelle deg om den flyktige modifikatoren. Vet du hva det er?"
"Noe som har med tråder å gjøre. Jeg husker ikke nøyaktig."
"Så hør etter. Her er noen tekniske detaljer for deg:"
"En datamaskin har to typer minne: globalt (vanlig) minne og minne innebygd i prosessoren. Det innebygde prosessorminnet er delt inn i registre, en første-nivå cache (L1), andre-nivå cache (L2), og tredje nivå (L3)."
"Disse minnetypene har forskjellige hastigheter. Det raskeste og minste minnet er registrene, deretter prosessorcachen (L1, L2, L3), og til slutt det globale minnet (det tregeste)."
"Globalt minne og prosessorcachen opererer med veldig forskjellige hastigheter, så Java-maskinen lar hver tråd lagre de mest brukte variablene i lokalt trådminne (i prosessorcachen)."
"Kan denne prosessen på en eller annen måte kontrolleres?"
"Ikke egentlig. Alt arbeidet gjøres av Java-maskinen. Den er veldig intelligent når det gjelder å optimalisere ytelsen."
"Men her er grunnen til at jeg forteller deg dette. Det er ett lite problem. Når to tråder jobber med samme variabel, kan hver enkelt lagre en kopi i sin egen lokale cache. Og så kan en tråd endre variabelen, men den andre ser kanskje ikke endringen, fordi den fortsatt jobber med sin egen kopi av variabelen."
"Vel, hva kan gjøres da?"
"Javas skapere ga et spesielt nøkkelord for denne situasjonen: flyktig. Hvis en variabel åpnes fra forskjellige tråder, må du merke den med den flyktige modifikatoren, slik at Java-maskinen ikke legger den inn i hurtigbufferen. Slik er det vanligvis utseende:"
public volatile int count = 0;
"Å, jeg husker. Du har allerede nevnt dette. Jeg vet dette allerede."
"Javisst gjør du det. Men du husket det bare da jeg fortalte det."
"Eh, vel, jeg har glemt litt."
"Repetisjon er læringens mor!"
"Her er noen nye fakta om den flyktige modifikatoren. Den flyktige modifikatoren garanterer bare at variabelen blir lest og skrevet på en sikker måte. Den garanterer ikke at den vil bli endret trygt."
"Hva er forskjellen?"
"Se på hvordan en variabel endres:"
Kode | Hva skjer egentlig: | Beskrivelse |
---|---|---|
|
|
Trinn 1. Variabeltellingens verdi kopieres fra globalt minne til et prosessorregister. Trinn 2. Trinn 3. |
"Wow! Så, alle variabler endres bare i prosessoren?"
"Japp."
"Og verdiene kopieres frem og tilbake: fra minne til prosessor og tilbake?"
"Japp."
"Den flyktige modifikatoren garanterer at når variabeltellingen åpnes, vil den bli lest fra minnet (trinn 1). Og hvis en tråd ønsker å tilordne en ny verdi, vil den definitivt være i globalt minne (trinn 3)."
"Men Java-maskinen garanterer ikke at det ikke vil være noen tråd som bytter mellom trinn 1 og 3."
"Så, å øke variabelen med 1 er faktisk tre operasjoner?"
"Ja."
"Og hvis to tråder samtidig ønsker å utføre count++, kan de forstyrre hverandre?"
"Ja, sjekk det ut:"
Tråd 1 | Tråd 2 | Resultat |
---|---|---|
|
|
|
"Så du kan få tilgang til variabelen, men det er fortsatt risikabelt å endre den?"
"Vel, du kan endre det, bare vær forsiktig ☺"
"Hvordan?"
" synkronisert er vår beste venn."
"Jeg skjønner."
GO TO FULL VERSION