Делает ли блокировка (objlocker) этот объект потокобезопасным для приложения в целом?И являются ли статические элементы автоматически потокобезопасными?

StackOverflow https://stackoverflow.com/questions/274344

Вопрос

Когда вы блокируете объект, блокируется ли этот объект во всем приложении?

Например, этот фрагмент из C # 3.0 вкратце описан в разделе 19.6.1 "Потокобезопасность и типы .NET Framework".:

static void AddItems(  )
  {
    for (int i = 0; i < 100; i++)
      lock (list)
        list.Add ("Item " + list.Count);

    string[] items;
    lock (list) items = list.ToArray(  );
    foreach (string s in items) Console.WriteLine (s);
  }

Блокирует ли первая:

lock (list)
        list.Add ("Item " + list.Count);

запретить другому потоку доступ:

lock (list) items = list.ToArray(  );

или и то, и другое может быть выполнено одновременно?

И делает ли CLR автоматически потокобезопасными ваши статические методы?Или это зависит от разработчика?

Спасибо, Джон

Это было полезно?

Решение

class UsefulStuff {
    object _TheLock = new object { };
    public void UsefulThingNumberOne() {
        lock(_TheLock) {
            //CodeBlockA
        }
    }
    public void UsefulThingNumberTwo() {
        lock(_TheLock) {
            //CodeBlockB
        }
    }
}

CodeBlockA и CodeBlockB не могут выполняться одновременно в разных потоках, поскольку оба они заблокированы в одном экземпляре объекта _TheLock.

Методы на _TheLock сами по себе они совершенно не затронуты.

Другие советы

Еще одна вещь, на которую следует обратить внимание, - это то, что статические конструкторы выполняются средой выполнения потокобезопасным способом.Если вы создаете синглтон и объявляете его как:

public class Foo
{
    private static Foo instance = new Foo();

    public static Foo Instance
    {
        get { return instance; }
    }
}

Тогда это будет потокобезопасно.Однако, если вы создадите экземпляр нового Foo внутри средство получения экземпляра, тогда вам нужно было бы написать свою собственную потокобезопасность (т.е.заблокировать объект)

Среда CLR автоматически не делает статические методы потокобезопасными;вы должны сделать это сами.

lock (список) использует этот объект в качестве блокировки, поэтому, если другой поток достигает другой точки с помощью lock (списка) (с тем же объектом 'list'), другой поток будет блокироваться до тех пор, пока первый поток не снимет блокировку.

Чтобы было ясно, lock(foo) не "блокирует объект foo", скорее, он получает блокировку, связанную с объектом foo, так что критическая секция (оператор в конструкции "lock(o) stmt") выполняется только тогда, когда текущий поток получил блокировку.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top