2016-02-23 4 views
0

Например, предположим, что у нас есть объект A, который указывает на ObjectB, который указывает на objectC.Поддерживает ли @synchronize объекты, на которые указывают другие объекты?

Затем мы делаем

@synchronized(objectA) { 
    [self doSomeStuff]; 
} 

Что защищен здесь от других потоков? Просто objectA, или objectB и objectC, и все, что любой объект ссылается на все пути вниз?

ответ

2

@synchronized(obj) {...} просто означает, что все, что в {...} не будет выполняться параллельно с любыми другими @synchronized(obj) «ы {...}.

I.e. Дано:

резьбы 1:

@synchronized(objectA) { 
    [self doSomeStuff]; 
} 

резьбы 2:

@synchronized(objectA) { 
    [self doSomeStuff]; 
} 

нити 3:

[self doSomeStuff]; 

Один из потока 1 или потока 2 будет блокировать в то время как другие выполняет doSomeStuff , но поток 3 будет весело ссылаться на doSomeStuff одновременно.

И, более прямо на ваш вопрос, это означает, что нет, существует абсолютно нулевая защита от параллелизма для всего, что doSomeStuff может сделать внутренне.

Если вы хотите, чтобы ваши объекты были «потокобезопасными», они должны быть спроектированы сверху донизу с учетом параллелизма (и это обычно не означает, что во всем мире имеется множество замков или примитивов синхронизации).

1

@synchronized(objectA) создает критический раздел. В вашем примере это гарантирует, что [self doSomeStuff] не будет выполняться одновременно разными потоками.

objectA используется только для определения того, какая неявно созданная рекурсивная блокировка будет использоваться. Критические разделы, созданные директивой @synchronized с тем же объектом, что и аргумент, не будут выполняться одновременно.

яблочная документации:

@synchronized директива представляет собой удобный способ для создания мьютекс замки на лету в коде Objective-C. Директива @synchronized делает то, что делает любой другой блокировки мьютекса - она ​​предотвращает одновременное получение одной и той же блокировки различных потоков от . В этом случае, однако, вам не нужно создавать объекты мьютекса или замка напрямую. Вместо этого вы, , просто используете любой объект Objective-C в качестве токена блокировки.

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

Смежные вопросы