Изменение объекта блокировки внутри секции @synchronized - PullRequest
6 голосов
/ 01 августа 2009

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

1

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

2

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

1 Ответ

9 голосов
/ 01 августа 2009

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...