Есть ли пример кода, в котором @synchronized заблокируется?

я действительно не могу думать ни о чем

Одна вещь, о которой я могу думать, это

@synchronized (self)
{
@synchronized (self){}
}

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

Другое, о чем я могу думать, это

@synchronized (A)
{
@synchronized (B){}
}

в одну ветку и

@synchronized (B)
{
@synchronized (A){}
}

в другой. Я прав здесь?

Как тогда избежать тупика? Какие-то простые правила?


person user4951    schedule 22.05.2012    source источник


Ответы (2)


Мое правило №1: никогда не блокировать ничего, что находится в открытом доступе.
Мое правило №2: никогда не обращаться к внешнему коду, удерживая блокировку.

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

person Rich O'Kelly    schedule 22.05.2012
comment
Мое правило — использовать только один и только один замок, и он виден всем. Это еще одно хорошее правило. - person user4951; 24.05.2012

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

«Лучшая» модель — это изоляция; сделать уровень перекрестного потока/очереди как можно меньше и сделать все, что находится за ним, изолированным от одного потока.

Core Data — хороший пример этого паттерна. Контексты управляемых объектов создаются для каждого потока, а CD управляет параллельным хранением данных полностью за кулисами с помощью исключительно хорошо протестированной части инфраструктуры.

person bbum    schedule 22.05.2012