c# - C # версия синхронизированного ключевого слова java?


У c # есть своя версия java «синхронизированного» ключевого слова?

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

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

или

public void doImportantStuff() {
   // trivial stuff

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



Answers


Сначала - большинство классов никогда не должны быть потокобезопасными. Используйте 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 т. Д. Для связи между потоками.

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




static object Lock = new object();

lock (Lock) 
{
// do stuff
}



У c # есть своя версия java «синхронизированного» ключевого слова?

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

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




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




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

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