Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
270 views
in Technique[技术] by (71.8m points)

ios - Does @synchronized guarantees for thread safety or not?

With reference to this answer, I am wondering is this correct?

@synchronized does not make any code "thread-safe"

As I tried to find any documentation or link to support this statement, for no success.

Any comments and/or answers will be appreciated on this.

For better thread safety we can go for other tools, this is known to me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

@synchronized does make code thread safe if it is used properly.

For example:

Lets say I have a class that accesses a non thread safe database. I don't want to read and write to the database at the same time as this will likely result in a crash.

So lets say I have two methods. storeData: and readData on a singleton class called LocalStore.

- (void)storeData:(NSData *)data
 {
      [self writeDataToDisk:data];
 }

 - (NSData *)readData
 {
     return [self readDataFromDisk];
 }

Now If I were to dispatch each of these methods onto their own thread like so:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      [[LocalStore sharedStore] storeData:data];
 });
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      [[LocalStore sharedStore] readData];
 });

Chances are we would get a crash. However if we change our storeData and readData methods to use @synchronized

 - (void)storeData:(NSData *)data
 {
     @synchronized(self) {
       [self writeDataToDisk:data];
     }
 }

 - (NSData *)readData
 { 
     @synchronized(self) {
      return [self readDataFromDisk];
     }
 }

Now this code would be thread safe. It is important to note that if I remove one of the @synchronized statements however the code would no longer be thread safe. Or if I were to synchronize different objects instead of self.

@synchronized creates a mutex lock on the object you are syncrhonizing. So in other words if any code wants to access code in a @synchronized(self) { } block it will have to get in line behind all previous code running within in that same block.

If we were to create different localStore objects, the @synchronized(self) would only lock down each object individually. Does that make sense?

Think of it like this. You have a whole bunch of people waiting in separate lines, each line is numbered 1-10. You can choose what line you want each person to wait in (by synchronizing on a per line basis), or if you don't use @synchronized you can jump straight to the front and skip all the lines. A person in line 1 doesn't have to wait for a person in line 2 to finish, but the person in line 1 does have to wait for everyone in front of them in their line to finish.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...