Běžné scénáře zneužití: Abychom zabránili duplicitním platbám objednávek způsobeným uživatelem, kteří omylem kliknou na tlačítko platby opakovaně, používáme zámek (číslo objednávky), abychom zajistili, že operace na objednávku může provést pouze jedno vlákno.
Tato myšlenka je dobrá, alespoň lepší než zámok (soukromý statický objekt pro zpracování tříd), protože efektem uzamčení čísla příkazu je uzamknout pouze operaci aktuálního řádu 1, a pokud uzamkne statickou proměnnou, tedy uzamkne všechny příkazy, způsobí, že všechny příkazy budou zařazeny do fronty, což je zjevně nerozumné.
Může tedy metoda zámku (číslo objednávky) zmíněná na začátku tohoto článku dosáhnout požadovaného efektu? Nejprve použijme kód k obnovení scénáře používání.
Pokud ignorujete uživatelské informace a další ověření, kód vypadá přibližně takto:
Pro klíčové slovo lock MSDN obsahuje informace, které lze najít na Baidu, a zdá se, že se nedoporučuje používat lock(string), přičemž důvod je stejný. Následující pasáž je převzata z rady MSDN ohledně zámkových řetězců:
Problém se zámkem ("myLock") nastává proto, že jakýkoli jiný kód používající stejný řetězec v procesu bude sdílet stejný zámek. Tato věta skrývá obrovský mechanismus, tedy "stejný řetězec".
Co je to "stejný řetězec"? Viz kód:
Jsou str1 a str2 stejná struna výše? Odpověď je ANO.
Podívejte se znovu:
Jsou str1 a str2 nad hlavou stále stejná struna? Odpověď je NE.
Dobře, vraťme se k otázce platby objednávky. V našem kódu lock(orderNumber), když uživatel omylem klikne několikrát po přejetí ruky, je orderNumber při zadávání této akce pokaždé stejný řetězec? Odpověď je NE. To znamená
Kód, který spravuje výše uvedené pořadí, ve skutečnosti nefunguje jako zámek.
Ve skutečnosti existují dva typy porovnání řetězců, viz kód:
První řádek výše uvedeného kódu vypíše True a druhý řádek False. Myslím, že chápeš, co MSDN myslí "stejný řetězec" bez mého vysvětlení.
Nejlepší řešení
Řešení pro optimální uzamykatelné řetězce:
Demo kód:
Na webu může být někdy použita globální proměnná, tato globální proměnná, když přistupuje více uživatelů současně, může vypadat abnormálně, v tuto chvíli nastavíme globální zámek, ale nevýhodou je, že všechny přístupy budou čekat postupně.
V některých případech může například stejný uživatel komentovat pouze jednou během 15 sekund, pokud je použit globální zámek, funkce komentářů bude velmi pomalá na zpracování, když počet uživatelů prudce vzroste, což výrazně ovlivní uživatelský zážitek.
V tuto chvíli,Můžeme nastavit zámek pro každého uživatele zvlášť, lock(string){...}, a název zámku lze definovat jako:Jméno metody + uživatelské IDTímto způsobem má každý uživatel nezávislý zámek a při hodnocení intervalu komentářů to neovlivní komentáře ostatních uživatelů.
(Konec)
|