Изменение объекта блокировки внутри @синхронизированного раздела

Можно ли выполнить одно из следующих действий? Правильно ли они заблокируют/разблокируют один и тот же объект? Почему или почему нет? Предположим, что существует много идентичных потоков с использованием глобальной переменной "obj", которая была инициализирована до начала всех потоков.

1.

@synchronized(obj) {
    [obj release];
    obj = nil;
}

2.

@synchronized(obj) {
    obj = [[NSObject new] autorelease];
}

Ответ 1

Короткий ответ: нет, они не будут правильно блокировать/разблокировать, и таких подходов следует избегать.

Мой первый вопрос заключается в том, почему вы хотели бы сделать что-то подобное, поскольку эти подходы с самого начала сводят на нет цели и преимущества использования @synchronized блока.

В вашем втором примере, когда поток изменяет значение obj, каждый последующий поток, который достигает блока @synchronized, будет синхронизироваться с новым объектом, а не с исходным объектом. Для N потоков вы должны явно создавать N автореализованных объектов, а среда выполнения может создавать до N рекурсивных блокировок, связанных с этими объектами. Переключение объекта, в котором вы синхронизированы в критическом разделе, является фундаментальным, но без потокового concurrency. Не делай этого. Когда-либо. Если несколько потоков могут безопасно обращаться к блоку одновременно, просто опустите полностью @synchronized.

В первом примере результаты могут быть undefined, и, конечно же, не то, что вы хотите. Если среда выполнения использует указатель объекта для поиска связанной блокировки, код может работать нормально, но синхронизация на nil не имеет ощутимого эффекта в моих простых тестах, так что вы снова используете @synchronized бесцельным способом, так как это не предлагает никакой защиты.

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