C # версия синхронизированного ключевого слова Java? - PullRequest
282 голосов
/ 12 февраля 2009

Есть ли у c # собственная версия ключевого слова "synchronized" в java?

т.е. в Java это может быть указано либо для функции, объекта или блока кода, например так:

public synchronized void doImportantStuff() {
   // dangerous code goes here.
}

или

public void doImportantStuff() {
   // trivial stuff

   synchronized(someLock) {
      // dangerous code goes here.
   }
}

Ответы [ 5 ]

437 голосов
/ 12 февраля 2009

Во-первых - большинству классов никогда не потребуется поточнобезопасность. Использовать YAGNI : применять потокобезопасность только тогда, когда вы знаете, что на самом деле собираетесь его использовать (и тестировать).

Для материала уровня метода есть [MethodImpl]:

[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}

Это также можно использовать для методов доступа (свойства и события):

private int i;
public int SomeProperty
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    get { return i; }
    [MethodImpl(MethodImplOptions.Synchronized)]
    set { i = value; }
}

Обратите внимание, что полевые события синхронизируются по умолчанию, в то время как автоматически реализуемые свойства не :

public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized

Лично мне не нравится реализация MethodImpl, поскольку она блокирует this или typeof(Foo) - что противоречит лучшей практике. Предпочтительным вариантом является использование ваших собственных замков:

private readonly object syncLock = new object();
public void SomeMethod() {
    lock(syncLock) { /* code */ }
}

Обратите внимание, что для событий типа поля реализация блокировки зависит от компилятора; в старых компиляторах Microsoft это lock(this) / lock(Type) - однако в более поздних компиляторах использует Interlocked обновлений - поэтому поточно-ориентированные без неприятных деталей.

Это позволяет более детально использовать и позволяет использовать Monitor.Wait / Monitor.Pulse и т. Д. Для связи между потоками.

Связанная запись в блоге (позже вновь ).

54 голосов
/ 12 февраля 2009
static object Lock = new object();

lock (Lock) 
{
// do stuff
}
38 голосов
/ 12 февраля 2009

Есть ли у c # собственная версия ключевого слова "synchronized" в java?

Нет. В C # вы явно lock ресурсы, которые вы хотите работать синхронно между асинхронными потоками. lock открывает блок; это не работает на уровне метода.

Однако основной механизм аналогичен, поскольку lock работает, вызывая Monitor.Enter (и впоследствии Monitor.Exit) во время выполнения. Java работает так же, согласно документации Sun .

7 голосов
/ 24 июля 2013

Обратите внимание, с полными путями строка: [MethodImpl(MethodImplOptions.Synchronized)] должна выглядеть как

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]

5 голосов
/ 12 февраля 2009

Вместо этого вы можете использовать оператор lock. Я думаю, что это может заменить только второй вариант. Также помните, что synchronized и lock должны работать с объектом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...