Zamki wielokrotne w C#

Zamki wielokrotne w C#

Nie, nie tak długo, jak blokujesz ten sam obiekt. Kod rekurencyjny skutecznie już ma blokadę i tak można kontynuować bez przeszkód.

lock(object) {...} jest skrótem do używania klasy Monitor. Jak wskazuje Marc, Monitor umożliwia ponowne wejście , więc powtarzające się próby zablokowania obiektu na którym bieżący wątek już ma blokadę będzie działać dobrze.

Jeśli zaczniesz blokować inne przedmioty, wtedy musisz być ostrożny. Zwróć szczególną uwagę na:

  • Zawsze ustalaj blokady na określoną liczbę obiektów w tej samej kolejności.
  • Zawsze zwalniaj blokady wstecz sekwencja do tego, w jaki sposób je zdobywasz.

Jeśli złamiesz którąś z tych zasad, masz prawie gwarancję, że w pewnym momencie pojawią się problemy z impasem .

Oto jedna dobra strona opisująca synchronizację wątków w .NET:http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

Zablokuj także jak najmniej obiektów na raz. Jeśli to możliwe, rozważ zastosowanie zamków gruboziarnistych. Chodzi o to, że jeśli możesz napisać swój kod w taki sposób, że istnieje graf obiektów i możesz uzyskać blokady na korzeniu tego grafu obiektów, to zrób to. Oznacza to, że masz jedną blokadę na tym obiekcie głównym i dlatego nie musisz się tak bardzo martwić o kolejność, w jakiej uzyskujesz/zwalniasz blokady.

(Jeszcze jedna uwaga, twój przykład nie jest technicznie rekurencyjny. Aby był rekurencyjny, Bar() musiałby się wywołać, zwykle w ramach iteracji).


Cóż, Monitor pozwala na ponowne wejście, więc nie możesz się zakleszczyć... więc nie:nie powinno


Jeśli wątek już utrzymuje blokadę, nie zablokuje się. Zapewnia to platforma .Net. Musisz tylko upewnić się, że dwa wątki nie próbują uzyskać tych samych dwóch blokad poza kolejnością przez jakiekolwiek ścieżki kodu.

Ten sam wątek może wielokrotnie nabyć tę samą blokadę, ale musisz upewnić się, że zwolnisz blokadę taką samą liczbę razy, jak ją nabyłeś. Oczywiście, jeśli do tego celu używasz słowa kluczowego „lock”, dzieje się to automatycznie.