2009-08-01 15 views
6

Czy mogę wykonać jedną z następujących czynności? Czy prawidłowo zablokują/odblokują ten sam obiekt? Dlaczego lub dlaczego nie? Załóżmy, że istnieje wiele identycznych wątków używających zmiennej globalnej "obj", która została zainicjowana przed rozpoczęciem wszystkich wątków.Zmiana obiektu blokowania w zsynchronizowanej sekcji @

1.

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

2.

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

Uwaga: Powiązane z http://stackoverflow.com/questions/1215330/ –

+1

Po przeczytaniu tego wpisu SO postanowiłem trochę dokładniej zbadać @synchronizację i napisać na niej post na blogu. Może się to okazać przydatne: http://rykap.com/objective-c/2015/05/09/synchronized.html – rjkaplan

+0

@rjkaplan Twój link jest zepsuty –

Odpowiedz

8

Krótka odpowiedź: nie, nie będą prawidłowo zablokować/odblokować, należy unikać tego rodzaju podejścia.

Moje pierwsze pytanie brzmi: dlaczego chciałbyś zrobić coś takiego, ponieważ te podejścia niwelują cele i zalety używania zsynchronizowanego bloku w pierwszej kolejności.

W drugim przykładzie, gdy wątek zmieni wartość obj, każdy kolejny wątek, który dotrze do zsynchronizowanego bloku, zostanie zsynchronizowany z nowym obiektem, a nie z oryginalnym obiektem. W przypadku wątków N użytkownik jawnie tworzył N autoreleased obiektów, a środowisko wykonawcze może tworzyć do N rekursywnych blokad powiązanych z tymi obiektami. Zamiana obiektu synchronizowanego w sekcji krytycznej jest podstawowym współdziałaniem bez wątków. Nie rób tego. Zawsze. Jeśli wiele wątków może bezpiecznie uzyskać równoczesny dostęp do bloku, po prostu całkowicie zignoruj ​​@ synchronizację.

W pierwszym przykładzie wyniki mogą być nieokreślone, a na pewno nie to, co chcesz. Jeśli środowisko wykonawcze używa tylko wskaźnika obiektu do znalezienia powiązanej blokady, kod może działać poprawnie, ale synchronizacja na nil nie daje odczuwanego efektu w moich prostych testach, więc znowu używasz @synchronized w bezsensowny sposób, ponieważ nie oferuje on ochrona w ogóle.

Szczerze, nie staram się być szorstki, ponieważ sądzę, że prawdopodobnie jesteś ciekawy konstrukcji. Po prostu tak sformułowałem, aby (miejmy nadzieję) uniemożliwić Tobie i innym osobom pisanie kodu, który jest fatalnie wadliwy, szczególnie jeśli założymy, że synchronizuje się prawidłowo. Powodzenia!

+0

W moim konkretnym przypadku (powód, dla którego znalazłem to Q/A) jest to, że chcę coś zrobić (przepraszam, brak dobrego formatowania w komentarzach) ... @synchornized (obj) {if (obj! = Nil) {... [do rzeczy, snip]; obj = nil}} '(* UWAGA: * Jestem pod ARC, więc dostaję moje' release' za darmo.Jednakże chcę, jeśli jest obiekt, zsynchronizować go, podczas gdy ja będę bałagan. nie obchodzi mnie to. – Olie

Powiązane problemy