Да, объект
является ссылочным типом, поэтому вы передаете ссылку на тот же объект, так что тот же объект будет использоваться каждым рабочим. Для блокировки используется объект, а не ссылка.
Оператор lock
будет отмечать экземпляр объекта, а не ссылочную переменную.
lock(x) {
...
}
Точно эквивалентен:
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
где x - экземпляр объекта ссылочного типа.
Так что да : -)
Я бы порекомендовал вам не передавать разделяемый объект, который вы используете для блокировки, иначе вы можете попасть в неприятные тупиковые ситуации. Используйте статический закрытый член класса для блокировки:
public class Worker
{
private static object _syncRoot = new object();
private Thread _workerThread;
private string _name;
public Worker(string name)
{
_name = name;
_workerThread = new Thread(new ThreadStart(DoWork));
_workerThread.Start();
}
private void DoWork()
{
while(true)
{
lock(_syncRoot)
{
Console.WriteLine(_name + "Doing Work");
}
}
}
}
То, что вы делаете, будет работать, но почему бы не сделать член _lockObject
членом Worker
класса статическим
? Он достигнет того же эффекта, но более объектно-ориентирован.
public class Worker
{
private static object _lockObject = new object();
private Thread _workerThread;
private string _name;
public Worker(string name)
{
_name = name;
_workerThread = new Thread(new ThreadStart(DoWork));
_workerThread.Start();
}
private void DoWork()
{
while(true)
{
lock(_lockObject)
{
Console.WriteLine(_name + "Doing Work");
}
}
}
}
РЕДАКТИРОВАТЬ : Ой! Я не видел ответа @Darin Dimitrov, который идентичен тому, что я разместил здесь. +1 тебе, Дарин.