Bežné scenáre zneužitia: Aby sme predišli duplicitnému plateniu objednávok spôsobenému opakovaným kliknutím používateľa na tlačidlo platby, používame zámok (číslo objednávky), aby sme zabezpečili, že operáciu na objednávke môže vykonať len jedno vlákno.
Táto myšlienka je dobrá, aspoň lepšia ako uzamknutie (súkromný statický objekt na spracovanie tried), pretože efektom uzamknutia čísla príkazov je zamknutie iba operácie aktuálneho 1 poradia, a ak uzamkne statickú premennú, teda zablokuje všetky príkazy, spôsobí, že všetky príkazy budú zaradené do fronty, čo je zjavne nerozumné.
Môže teda metóda zámku (číslo objednávky) spomenutá na začiatku tohto článku dosiahnuť požadovaný efekt? Najskôr použime nejaký kód na obnovenie scenára používania.
Ak ignorujete používateľské informácie a ďalšie overenia, kód vyzerá približne takto:
Pre kľúčové slovo lock MSDN obsahuje informácie, ktoré sa dajú nájsť na Baidu, a zdá sa, že sa neodporúča používať lock(string), pričom dôvod je rovnaký. Nasledujúci úryvok je prevzatý z rád MSDN ohľadom zámkových reťazcov:
Problém so zámkom ("myLock") nastáva preto, že akýkoľvek iný kód používajúci rovnaký reťazec v procese zdieľa rovnaký zámok. Táto veta skrýva obrovský mechanizmus, teda "ten istý reťazec".
Čo je to "ten istý reťazec"? Pozri kód:
Sú str1 a str2 tá istá struna vyššie? Odpoveď je ÁNO.
Pozri znova:
Sú str1 a str2 nad stále tou istou strunou? Odpoveď je NIE.
Dobre, vráťme sa k otázke platby objednávky. V našom kóde lock(orderNumber), keď používateľ omylom klikne niekoľkokrát po pretiahnutí ruky, je orderNumber zadávajúci túto akciu zakaždým rovnaký reťazec? Odpoveď je NIE. To znamená, že
Kód, ktorý spracováva vyššie uvedené poradie, v skutočnosti nefunguje ako zámok.
V skutočnosti existujú dva typy porovnávania reťazcov, pozri kód:
Prvý riadok vyššie uvedeného kódu vypíše True a druhý riadok False. Myslím, že rozumieš, čo MSDN myslí pod "rovnakým reťazcom" bez môjho vysvetlenia.
Najlepšie riešenie
Riešenia pre optimálne uzamykacie reťazce:
Demo kód:
Na webovej stránke sa niekedy používa globálna premenná, táto globálna premenná, keď viacerí používatelia pristupujú súčasne, môže vyzerať abnormálne, v tomto čase nastavíme globálny zámok, ale nevýhodou je, že všetky prístupy budú čakať postupne.
V niektorých scenároch môže ten istý používateľ komentovať len raz za 15 sekúnd, ak sa použije globálny zámok, funkcia komentárov bude veľmi pomalá na spracovanie, keď počet používateľov prudko stúpne, čo výrazne ovplyvní používateľský zážitok.
V tomto čase,Môžeme nastaviť zámok pre každého používateľa individuálne, lock(string){...}, a názov zámku môžeme definovať ako:Názov metódy + ID používateľaTýmto spôsobom má každý používateľ nezávislý zámok a pri hodnotení intervalu komentárov to neovplyvní komentáre ostatných používateľov.
(Koniec)
|