Как этот рекурсивный синхронизированный вызов не тупик? - PullRequest
2 голосов
/ 22 января 2012

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

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

Это что-то особенное, что делает @synchronized или это особенность блокировок мьютекса?


Пример кода, который работает:

- (NSUInteger)testA
{
    @synchronized(self.class)
    {
        NSLog(@"Doing something in A");
    }
    return 1;
}

- (void)testB
{
    @synchronized(self.class)
    {
        NSLog(@"Doing something in B");
        NSLog(@"A returned: %i", [self testA]);
    }
}

При вызове testB вывод будет:

Doing something in B
Doing something in A
A returned: 1

1 Ответ

11 голосов
/ 22 января 2012

Комментарий Маурисио верен. От TOCPL :

Функция синхронизации Objective-C поддерживает рекурсивный и реентерабельный код. Поток может использовать один семафор несколько раз рекурсивным способом; другие потоки блокируются от его использования до тех пор, пока поток не снимет все блокировки, полученные с его помощью; то есть каждый блок @synchronized() выходит нормально или через исключение.

...