Почему плохо использовать lock(this)? - C#
Формулировка задачи:
почитав информацию из разных источников по этой теме, я ничего не понял
Магистры параллелизма, приведите, пожалуйста, наглядные примеры кода, которые иллюстрируют %topicname%
Когда можно использовать lock(this) и когда нельзя?
Изменится ли как-то состояние объекта, когда он заблокируется?
Решение задачи: «Почему плохо использовать lock(this)?»
textual
Листинг программы
interface IAsyncPrinter
{
Task PrintAsync(string message);
}
// Метод не знает ничего о потокобезопасности объекта resultsPrinter,
// поэтому перестраховывается использованием lock
void DoWork(IAsyncPrinter resultsPrinter)
{
var taskOne = Task.Run(() =>
{
lock (resultsPrinter)
{
var t = resultsPrinter.PrintAsync("First part completed!");
Thread.Sleep(1);
t.Wait();
}
});
var taskTwo = Task.Run(() =>
{
lock (resultsPrinter)
{
var t = resultsPrinter.PrintAsync("Second part completed!");
Thread.Sleep(1);
t.Wait();
}
});
Task.WaitAll(taskOne, taskTwo);
}
class LockThisThreadSafeAsyncPrinter : IAsyncPrinter
{
public Task PrintAsync(string message)
{
return Task.Run(() =>
{
lock (this)
{
// имитируем запись в медленный потоконебезопасный приёмник
Thread.Sleep(500);
}
Console.WriteLine(message); // консоль потокобезопасна
});
}
}
class NoLockThisThreadSafeAsyncPrinter : IAsyncPrinter
{
private object _locker = new object();
public Task PrintAsync(string message)
{
return Task.Run(() =>
{
lock (_locker)
{
// имитируем запись в медленный потоконебезопасный приёмник
Thread.Sleep(500);
}
Console.WriteLine(message); // консоль потокобезопасна
});
}
}
void Main()
{
Console.WriteLine("Block 1");
IAsyncPrinter asyncPrinter = new NoLockThisThreadSafeAsyncPrinter();
DoWork(asyncPrinter);
Console.WriteLine("Block 2: deadlock");
asyncPrinter = new LockThisThreadSafeAsyncPrinter();
DoWork(asyncPrinter);
}