1

What is synchronized?

What is it used for?

What are the differences between the java synchronized and the objective-c @synchronized?

Popeye
  • 10,831
  • 9
  • 52
  • 85

2 Answers2

5

Concurrent access of an object from more then one independent thread has always presented a consistent set of issues across all programming languages, and Java and Objective-C are no exceptions. To help resolve these issues both language support what is known as the synchronized directive. Any block of code that is marked with the synchronized directive is protected against more then one thread executing it at anyone time.

Synchronized is used to make a block of code thread safe. It makes so only one thread can execute that code block at anyone given time.

There aren't actually many differences between the two languages and how they use the synchronized directive. The only major difference is that in Java, synchronized is actually a keyword and can be used as a method modifier. Whereas to accomplish the equivalent in Objective-C you have to use @synchronized(self) on the outermost block of code in your method. Beyond these minor limitations, you can @synchronized in Objective-C in exactly the same way you would synchronized in java. To illustrate these minor differences and show how you can make your code thread save by using synchronized see the examples below.

Java

public class MyThreadSafeExample {
    public synchronized void safeMethod() {
        // Here you would enter the code you want to be thread safe.
    }
}

Objective-C

@interface MyThreadSafeExample : NSObject

- (void)safeMethod;

@end

@implementation MyThreadSafeExample

- (void)safeMethod
{
    @synchronized(self) {
        // Here you would enter the code you want to be thread safe.
    }
}

@end

Notice that except for the obvious syntax differences there isn't any huge differences between the two and both of these will act in exactly the same way.

Note as well that in Java you can make it look even more like Objective-C doing the following

public class MyThreadSafeExample {
    public void safeMethod() {
        synchronized (this) {
            // Here you would enter the code you want to be thread safe.
        }
    }
}

Notice it is no longer a method modifier but all of them would still do the exact same thing and make the code block thread safe and both the Java version are basically the same.

Popeye
  • 10,831
  • 9
  • 52
  • 85
5

At the high level, both could be described as "mechanisms for ensuring only a single thread of execution is executing a block of code at a time". That is, they make a scope of code atomic; only executable from a single thread at a time.

While that makes the execution thread safe, it does not make the program thread safe. Atomicity does not guarantee thread safety. What's the difference between the atomic and nonatomic attributes?

Note: That they are nearly identical should come as no surprise. Java was created as a direct derivation of Objective-C.

One difference: In Java, the synchronized keyword applied to methods affects all methods of that class on any one instance. You can't have one set of methods synchronize on state A and another set of methods synchronize on state B. Objective-C doesn't have this form.

Both Objective-C and Java also have a @synchonized(ARG) { ... } (Java drops the @) construct serializes the scope { ... } by holding a lock keyed on ARG during execution of said scope (wherein a second execution of said scope simultaneously will block until done).

Thus, you can have many different serialization gateways within any one class or, even, across classes.

For example, if you have a class with a mutable array instance variable, you could:

- (void)swap {
     @synchonized(_mutableArray) {
          ... swap some elements here ...
     }
 }

 - (void)sort {
     @synchonized(_mutableArray) {
          ... sort some elements here ...
     }
 }

And you can mix @synchronized() scopes within a method:

- (void)thisIsntAGoodIdeaButJustAnExample
     @synchonized(_mutableArray) {
          ... sort some elements here ...
          @synchronized(self) {
              ... some operation that requires both _mutableArray and self to be locked ...
          }
     }
 }

You can also use @synchronized([SomeClass class]) { ... } or @synchronized(someGlobal) { ... }.

Community
  • 1
  • 1
bbum
  • 160,467
  • 23
  • 266
  • 355