Java-подобная синхронизация потоков в C # - PullRequest
2 голосов
/ 26 октября 2009

Я программист на Java и знаю несколько вещей о многопоточности в Java.

В Java я могу заблокировать метод с помощью синхронизированного ключевого слова:

private int a;
private int b;
private int c;
private synchronized void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}

Я искал в msdn и увидел, что в c # есть несколько игрушек для игры с потоками. Например, monitor.Enter, monitor.Exit, lock или advanced mutex.

Но мне нужно синхронизировать один метод. Что эквивалентно этому в c #?

Заранее спасибо.

Ответы [ 5 ]

6 голосов
/ 26 октября 2009

В C # нет прямого эквивалента, но вы можете сделать то же самое с этим:

private readonly object changeVarsLockObject = new object();

private void changeVars()
{
  lock(changeVarsLockObject)
  {
    a = 4;
    b = 2;
    c = a+b;
  }
}
4 голосов
/ 26 октября 2009

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

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

Синхронизация сложна , и в идеале вам нужно знать о ней больше, чем «несколько вещей», если вы хотите избежать взаимоблокировок и проблем видимости, которые почти никогда не появляются во время тестирования или способствуют отладке. Принятие, возможно, неполного понимания синхронизации на одном языке и попытка перенести ее на другой язык с другими примитивами и, вероятно, с другой моделью памяти - это путь к катастрофе.

Так что, хотя это не тот однострочный ответ, который вы искали, я собираюсь утверждать, что любой однострочный ответ обречен на провал без знания всей экосистемы, чтобы его поддержать. Таким образом, вам следует прочитать хорошую книгу / учебное пособие по синхронизации в C #, а не пытаться перевести ключевое слово Java Experience по ключевому слову.

4 голосов
/ 26 октября 2009

Прямой эквивалент этого - использование блокировки (this):

private void ChangeVars()
{
    lock (this) {
        a = 4;
        b = 2;
        c = a+b;
    }
}

или действительно с использованием метода MethodImplAttribute, как описано Р. Бемроузом, что равносильно тому же:

[MethodImpl(MethodImplOptions.Synchronized)]
private void ChangeVars()
{
    a = 4;
    b = 2;
    c = a+b;
}

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

private object monitor = new object();
private void ChangeVars()
{
    lock (monitor) {
        a = 4;
        b = 2;
        c = a+b;
    }
}
4 голосов
/ 26 октября 2009

Примерно так: mayhaps:

using System.Runtime.CompilerServices;

...

private int a;
private int b;
private int c;

[MethodImpl(MethodImplOptions.Synchronized)]
private void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}
3 голосов
/ 26 октября 2009

Предпочтительное решение - заключить тело метода в оператор lock.

internal class Foo
{
   private Object lockObject = new Object();

   private void ChangeVars()
   {
      lock (this.lockObject)
      {
         // Manipulate the state.
      }
   }
}

Вы также можете использовать декларативную синхронизацию, но у этого есть очевидный недостаток, который вы должны получить из ContextBoundObject, и все методы, украшенные атрибутом Synchronization, имеют тот же объект блокировки, ограничивающий степень детализации блокировки.

internal class Foo : ContextBoundObject
{
   [Synchronization]
   private void ChangeVars()
   {
      // Manipulate the state.
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...