"Hej, Amigo! Vi har et universalmiddel - en kur mod alle sygdomme. Som vi allerede har set, er ukontrolleret trådskift et problem."
"Hvorfor kan trådene ikke selv bestemme, hvornår de skal skifte til den næste tråd? Gør alt, hvad de skal gøre og signaler derefter, "Jeg er færdig!"?"
"At lade tråde selv styre switching ville være et endnu større problem. Antag, at du har en dårligt skrevet kode, og tråden aldrig overgiver CPU'en. Dengang fungerede det sådan. Og det var noget af et mareridt."
"Okay. Hvad er så løsningen?"
" Blokerer andre tråde. Sådan fungerer det."
Det blev klart, at tråde interfererer med hinanden, når de forsøger at bruge delte objekter og/eller ressourcer . Ligesom vi så i eksemplet med konsoludgang: Der er én konsol og alle trådene output til den. Det er rodet.
Så en speciel genstand blev opfundet: mutexen . Det er som et skilt på en badeværelsesdør, hvor der står «tilgængelig / optaget» . Det har to tilstande: objektet er tilgængeligt eller optaget . Disse tilstande kaldes også «låst» og «ulåst».
Når en tråd har brug for et objekt, der deles med andre tråde, kontrollerer den mutex, der er knyttet til objektet. Hvis mutex'en er låst op, låser tråden den (markerer den som «optaget») og begynder at bruge den delte ressource. Efter at tråden har gjort sin forretning, låses mutex'en op (markeret som «tilgængelig»).
Hvis tråden vil bruge objektet og mutex'en er låst, så sover tråden mens den venter. Når mutex'en endelig er låst op af den optagede tråd, vil vores tråd straks låse den og begynde at køre. Analogien med et badeværelsesdørskilt er perfekt.
"Så hvordan arbejder jeg med en mutex? Skal jeg lave specielle objekter?"
"Det er meget enklere end som så. Javas skabere indbyggede denne mutex i Object-klassen. Så du behøver ikke engang at oprette den. Det er en del af hvert objekt. Sådan fungerer det hele:"
Kode | Beskrivelse |
---|---|
|
Swap-metoden bytter værdierne af variablerne navn1 og navn2.
Hvad kan der ske, hvis det kaldes fra to tråde på samme tid? |
Faktisk kodeudførelse | Koden for den første tråd | Kode for den anden tråd |
---|---|---|
|
|
|
Bundlinjen |
---|
Værdierne af variablerne blev byttet to gange, og vendte tilbage til deres oprindelige pladser. |
Vær opmærksom på søgeordet synkroniseret .
"Ja, hvad betyder det?"
"Når en tråd indtaster en kodeblok, der er markeret som synkroniseret, låser Java-maskinen øjeblikkeligt mutexet for objektet angivet i parentes efter ordet synkroniseret. Ingen anden tråd kan indtaste denne blok, før vores tråd forlader den. Så snart vores tråd forlader den. blokken, der er markeret som synkroniseret, låses mutexen øjeblikkeligt og automatisk op og vil være tilgængelig til at blive erhvervet af en anden tråd."
Hvis mutex'en er optaget, vil vores tråd stå stille og vente på, at den frigøres.
"Så enkelt og så elegant. Det er en smuk løsning."
"Ja. Men hvad tror du, der vil ske i denne sag?"
Kode | Beskrivelse |
---|---|
|
Swap- og swap2-metoderne deler samme mutex (det dette objekt). |
Hvad sker der, hvis en tråd kalder swap-metoden og en anden tråd kalder swap2-metoden?
"Da mutex'en er den samme, vil den anden tråd skulle vente, indtil den første tråd forlader den synkroniserede blok. Så der vil ikke være nogen problemer med samtidig adgang."
"Godt gået, Amigo! Det er det rigtige svar!"
Nu vil jeg gerne påpege, at synkroniseret kan bruges til at markere ikke kun kodeblokke, men også metoder. Her er hvad det betyder:
Kode | Hvad sker der virkelig |
---|---|
|
|
GO TO FULL VERSION