2009-12-09 3 views
16

Можно создать дубликат:
Difference between lock(locker) and lock(variable_which_I_am_using)Почему блокировки выполняются на отдельных объектах?

Во всех «потокобезопасных» примеры кода я видел, они запирают на отдельный фиктивный объект. Почему автоматические блокировки непосредственно выполняются над данными?

+0

большой вопрос, это была моя первая мысль тоже. – Russell

+1

В интересах того, чтобы помочь людям наилучшим образом найти ответ, который они ищут, этот вопрос не должен быть закрыт. @Bill, так называемый точный дублирующий вопрос неловко озаглавлен и сформулирован и не содержит четкого определения фундаментального вопроса, в отличие от этого вопроса. Я считаю, что этот вопрос гораздо чаще привлекает внимание в поисках. Поэтому я проголосовал за повторное открытие. – Ash

ответ

18

Блокировка на отдельном объекте private дает вам гарантию, что никто не блокирует этот объект.

Если вы заблокируете данные, и тот же самый фрагмент данных виден снаружи, вы потеряете эту гарантию. Например:

public class MyObject 
{ 
    public void SharedMethod() 
    { 
     lock (this) 
     { 
      // Do stuff 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyObject o = new MyObject(); 

     lock (o) 
     { 
      new Thread(() => 
      { 
       // Gets blocked 2s because of external lock 
       o.SharedMethod(); 
      }).Start(); 

      Thread.Sleep(2000); 
     } 
    } 
} 
+0

Хороший пример проблемы. – RichardOD

+0

Думаю, я понял. Если у вас есть отдельный фиктивный объект, то, блокируя объект, который вы хотите использовать, вы не мешаете ему ничего делать? – RCIX

+0

Я имею в виду, когда вы пытаетесь вызвать метод на этом объекте, который должен что-то синхронизировать. – RCIX

2

В блоге Эрика Гуннерсона есть замечательные материалы. См. here и here.

8

Jeff Richter (автор CLR Via C#) объясняет, почему в этой статье на Safe Thread Synchronization.

В частности, в этой статье раздел «Почему Великая идея не так велика» отвечает на ваш вопрос.

Это на самом деле глава из книги CLR Via C#.

Таким образом, наличие частного объекта в качестве объекта «synclock» позволяет вашему классу инкапсулировать и контролировать любые блокировки ваших потребностей в классе. Поэтому независимо от того, сколько клиентов использует ваш класс, блокировка выполняется последовательно и правильно.

+0

+1. Я собирался указать на его книгу, но эта статья фактически такая же! – RichardOD

+0

Если объект должен быть заблокирован во время определенных операций, и если внешнему коду может потребоваться выполнить две или более операции без блокировки, выпущенной между ними, объект должен либо открыть блокировку, либо методы для ее приобретения и выпуска. Нарушение не приведет к тому, что внешний код не сможет правильно выполнить то, что ему нужно. – supercat

 Смежные вопросы

  • Нет связанных вопросов^_^