Šis straipsnis yra veidrodinis mašininio vertimo straipsnis, spauskite čia norėdami pereiti prie originalaus straipsnio.

Rodinys: 46741|Atsakyti: 7

[Šaltinis] Nepastovus vs. užrakintas vs. užraktas

[Kopijuoti nuorodą]
Paskelbta 2018-08-27 14:40:35 | | |
Tarkime, yra klasė, kurioje yra viešas int skaitiklio laukas, kurį galima pasiekti keliomis gijomis, ir šis skaičius tik didės arba sumažės.

Įtraukiant šį lauką, kuri iš šių schemų turėtų būti naudojama ir kodėl?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(nuoroda this.counter);
  • Pakeiskite skaitiklio prieigos modifikatorių į viešą nepastovų


Blogiausia (nė vienas iš jų iš tikrųjų neveikia)

Pakeiskite skaitiklio prieigos modifikatorių į viešą nepastovų

Šis metodas iš tikrųjų nėra saugus, o esmė apie nepastovumą yra ta, kad kelios gijos, veikiančios keliuose procesoriuose, buferinius duomenis ir pertvarko vykdomas instrukcijas.

Jei jis nepastovus, kai procesorius A padidėja verte, procesorius B turi šiek tiek palaukti, kol pamatys padidėjusią vertę, o tai gali sukelti problemų.

Jei jis nepastovus, tai užtikrina, kad abu procesoriai vienu metu matys tą pačią vertę. Tačiau tai neišvengia kryžminių skaitymo ir rašymo operacijų.

Kintamojo vertės pridėjimas iš tikrųjų trunka tris veiksmus

1. Skaitymas, 2. Pridėti 3. Rašyti

Tarkime, kad gija A skaitiklio reikšmę nuskaito kaip 1 ir nėra pasirengusi didinti, tada gija B taip pat nuskaito skaitiklio reikšmę kaip 1, o tada abi gijos pradeda atlikti inkrementines ir rašymo operacijas. Galutinio skaitiklio vertė yra 2. Tai neteisinga, abi gijos atliko padidinimo operaciją, o teisingas rezultatas turėtų būti 3. Taigi ženklinti jį kaip lakų yra tiesiog nesaugu.

Tai geriau

lock(this.locker) this.counter++;

Tokiu būdu tai saugu (žinoma, nepamirškite užrakinti visur, kur norite pasiekti this.counter). Tai neleidžia jokiai kitai gijai vykdyti užrakinto kodo. Tai taip pat apsaugo nuo aukščiau minėtos kelių procesorių instrukcijų sekos problemos. Problema ta, kad užraktas veikia lėtai, o jei naudojate užraktą kitose nesusijusiose vietose, jis gali užblokuoti kitas gijas.

Geriausias

Interlocked.Increment(nuoroda this.counter);

Tai saugu ir labai efektyvu. Jis atlieka skaitymą, didinimą, rašymą tris operacijas viename atome, nepertraukiamas viduryje. Kadangi tai neturi įtakos kitam kodui, jums nereikia prisiminti spynų kitur. Ir tai taip pat labai greita (kaip MSDN sako, šiandienos procesoriai, tai dažnai tik instrukcija).

Bet nesu visiškai tikras, ar jis taip pat gali išspręsti procesoriaus instrukcijų užsakymo problemą, ar jį reikia naudoti kartu su nepastoviu ir šiuo prieaugiu.

Papildymas: Kokias problemas gerai išsprendžia lakus?

Kadangi nepastovus negali užkirsti kelio kelių gijų, ką jis gali padaryti? Geras pavyzdys yra tai, kad turite dvi gijas, viena visada rašo į kintamąjį, tarkime, šis kintamasis yra queneLength, o kitas visada skaito duomenis iš šio kintamojo. Jei queueLenght nėra nepastovus, gija A gali skaityti 5 kartus, bet gija B gali matyti uždelstus duomenis arba net duomenis neteisinga tvarka. Vienas iš sprendimų yra naudoti užraktą, tačiau šiuo atveju taip pat galite naudoti lakiąją. Tai užtikrina, kad gija B visada matys naujausius duomenis, parašytus gijos A, tačiau ši logika veikia tik tuo atveju, jei jų neskaitote rašydami ir jei nerašote skaitydami. Kai kelios gijos nori atlikti skaitymo, modifikavimo ir rašymo operacijas, turite naudoti užrakintą arba užrakinti.





Ankstesnis:Java MD5 šifravimo metodas
Kitą:Linq įgyvendina ne SQL ir sąlyginėse užklausose
Paskelbta 2018-08-29 16:21:42 |
Sveiki, kodas, kurį padarėte anksčiau, kad sujungia highcharts sukrautos histogramos ir gręžimo histogramos? Norėčiau paklausti, ar galite atsiųsti kodą, kurį galima redaguoti https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light sąsajoje?
Paskelbta 2018-08-29 16:22:13 |
Visas tinklas yra tik jūsų išteklius.
Paskelbta 2018-08-29 16:22:55 |
Nes ankstesni prieš 90 metų negalėjo palikti žinutės. Taigi
Paskelbta 2018-08-29 16:40:40 |
Ar patogu pridėti kontaktinę informaciją? Pasitarkite su jumis
 Savininkas| Paskelbta 2018-09-15 13:10:16 |
privatus statinis int safeInstanceCount = 0; Dirbkite su atomais
System.Threading.Interlocked.Increment(nuoroda safeInstanceCount); Savaiminis didinimas 1
System.Threading.Interlocked.Decrement(nuoroda safeInstanceCount); Savęs minusas 1
Paskelbta 2020-05-21 16:43:54 |
Padėkite savininkui dalytis
 Savininkas| Paskelbta 2020-06-11 15:00:16 |
1. Koncepcija

Kelių gijų aplinkoje operacijos, kurių nepertraukia gijų planavimo mechanizmai; Kai ši operacija prasideda, ji veikia iki galo, be jokio konteksto jungiklio (perjungimo į kitą giją).

2. Klasė

System.Threading.Interlocked statinė klasė

3. Dažniausiai naudojamos funkcijos (žr. likusias)

1. viešas statinis int Decrement (nuoroda į vietą); Sumažinkite nurodyto kintamojo vertę atominės operacijos forma ir išsaugokite rezultatą

Atitinka lock(obj){i--; }

2. viešas statinis int prieaugis (nuoroda į vietą); Padidinkite nurodyto kintamojo vertę atominės operacijos forma ir išsaugokite rezultatą

Atitinka lock(obj){i++; }
Atsakomybės apribojimas:
Visa programinė įranga, programavimo medžiaga ar straipsniai, kuriuos skelbia Code Farmer Network, yra skirti tik mokymosi ir mokslinių tyrimų tikslams; Aukščiau nurodytas turinys negali būti naudojamas komerciniais ar neteisėtais tikslais, priešingu atveju vartotojai prisiima visas pasekmes. Šioje svetainėje pateikiama informacija gaunama iš interneto, o ginčai dėl autorių teisių neturi nieko bendra su šia svetaine. Turite visiškai ištrinti aukščiau pateiktą turinį iš savo kompiuterio per 24 valandas nuo atsisiuntimo. Jei jums patinka programa, palaikykite autentišką programinę įrangą, įsigykite registraciją ir gaukite geresnes autentiškas paslaugas. Jei yra kokių nors pažeidimų, susisiekite su mumis el. paštu.

Mail To:help@itsvse.com