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

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

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

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

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

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

3 ответа

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


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

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

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

Это может быть использовано следующим образом:

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

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

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

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

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

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

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

Другие вопросы по тегам