Nie, pod warunkiem, że blokujesz ten sam obiekt. Kod rekurencyjny skutecznie już posiada blokadę i może działać bez przeszkód.
lock(object) {...}
jest skrótem do używania klasy Monitor . Jak wskazuje Marc , Monitor
pozwala na ponowne wejście , więc wielokrotne próby zablokowania obiektu, na którym bieżący wątek ma już blokadę, będą działać dobrze.
Jeśli zaczniesz blokować różne obiekty, wtedy musisz być ostrożny. Zwróć szczególną uwagę na:
- Zawsze ustawiaj blokady na określonej liczbie obiektów w tej samej kolejności.
- Zawsze zwalniaj blokady w odwrotnej kolejności do sposobu ich zdobycia.
Jeśli złamiesz którąkolwiek z tych zasad, masz prawie gwarancję, że w pewnym momencie wystąpią problemy z zakleszczeniem .
Oto jedna dobra strona internetowa opisująca synchronizację wątków w .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Ponadto blokuj jak najmniej obiektów naraz. W miarę możliwości rozważ zastosowanie gruboziarnistych zamków . Chodzi o to, że jeśli możesz napisać swój kod w taki sposób, że istnieje graf obiektowy i możesz uzyskać blokady w katalogu głównym tego grafu obiektowego, zrób to. Oznacza to, że masz jedną blokadę na tym obiekcie root i dlatego nie musisz się tak bardzo martwić o kolejność, w której nabywasz / zwalniasz blokady.
(Jeszcze jedna uwaga, twój przykład nie jest technicznie rekurencyjny. Aby był rekurencyjny, Bar()
musiałby wywołać siebie, zwykle jako część iteracji.)