SyncLock на двух объектах - PullRequest
       10

SyncLock на двух объектах

2 голосов
/ 17 августа 2010

Предположим, у меня есть два объекта a и b .

Я хочу синхронизировать оба объекта.

Возможно ли это?Это можно сделать с помощью вложенных операторов SyncLock?В чем опасность такой операции?

Редактировать

Может быть, я должен спросить, как один рефакторинг может избежать тупиков?

Ответы [ 3 ]

5 голосов
/ 17 августа 2010

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


РЕДАКТИРОВАТЬ: ответить на второй вопроспри попытке принудительно установить правильный порядок блокировок:

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

public void LockAndDoWork(Action action)
{
 lock(lockObject1)
 {
  lock(lockObject2)
  {
    action();
  }
 }
}

.это:

Thread1: LockAndDoWork(() => {do some work....});
Thread2: LockAndDoWork(() => {do some other work...});

Это может помочь избежать этой потенциальной проблемы - это особенно полезно, если можно ограничить видимость для этих объектов из клиентского кода

1 голос
/ 17 августа 2010

Может быть, я должен спросить, как один рефакторинг может избежать тупиков?

Определение всех синхронизирующих блокировок в строгом порядке приоритетов и всегда в первую очередь с наивысшим приоритетом.

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

0 голосов
/ 17 августа 2010

Это можно сделать, но вам нужно рассмотреть, что произойдет, если 2 потока, выполняющие этот код, попытаются получить обе блокировки одновременно - например, если поток 1 имеет блокировку для объекта 1, а поток 2 имеет блокировку для объекта 2? Кий тупик.

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

...