7

Can I do any of the following? Will they properly lock/unlock the same object? Why or why not? Assume there are many identical threads using global variable "obj", which was initialized before all threads started.

1.

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

2.

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

1 Answer 1

9

Short answer: no, they won't properly lock/unlock, and such approaches should be avoided.

My first question is why you'd want to do something like this, since these approaches nullify the purposes and benefits of using a @synchronized block in the first place.

In your second example, once a thread changes the value of obj, every subsequent thread that reaches the @synchronized block will synchronize on the new object, not the original object. For N threads, you'd be explicitly creating N autoreleased objects, and the runtime may create up to N recursive locks associated with those objects. Swapping out the object on which you synchronize within the critical section is a fundamental no-no of thread-safe concurrency. Don't do it. Ever. If multiple threads can safely access a block concurrently, just omit the @synchronized entirely.

In your first example, the results may be undefined, and certainly not what you want, either. If the runtime only uses the object pointer to find the associated lock, the code may run fine, but synchronizing on nil has no perceptible effect in my simple tests, so again you're using @synchronized in a pointless way, since it offers no protection whatsoever.

I'm honestly not trying to be harsh, since I figure you're probably just curious about the construct. I'm just wording this strongly to (hopefully) prevent you and others from writing code that is fatally flawed, especially if under the assumption that it synchronizes properly. Good luck!

1
  • In my particular case (the reason I found this Q/A) is that I want to do something like (sorry, no good formatting in comments)... @synchornized(obj) { if (obj != nil) { ...[do stuff, snip]; obj = nil } } (*NOTE: * I'm under ARC, so I get my release for free. What I want is, if there's an obj, to sync it while I mess around. If it's nil, I don't really care.
    – Olie
    May 27, 2016 at 18:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.