@synchronized是否保证线程安全? [英] Does @synchronized guarantees for thread safety or not?

查看:236
本文介绍了@synchronized是否保证线程安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参考此 answer a>,我想知道这是正确的吗?


@synchronized不会使任何代码线程安全


因为我试图找到任何文档或链接来支持这个声明,所以没有成功。



任何意见和/


为了更好的线程安全,我们可以选择其他工具。

解决方案

@synchronized 确保代码线程安全,如果它正确使用。



例如:



假设我有一个访问非线程安全数据库的类。我不想同时读取和写入数据库,因为这可能会导致崩溃。



所以说我有两个方法。

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

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



现在如果我把这些方法分派到自己的线程上:

  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];
});

我们很可能会崩溃。但是如果我们改变我们的storeData和readData方法使用 @synchronized

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

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

现在这个代码将是线程安全的。重要的是注意,如果我删除 @synchronized 语句中的一个,但是代码将不再是线程安全的。或者如果我要同步不同的对象,而不是 self



@synchronized 在要同步的对象上创建互斥锁。所以换句话说,如果任何代码想要访问 @synchronized(self){} 块中的代码,它将必须在同一行内的所有以前的代码块。



如果我们要创建不同的localStore对象, @synchronized(self) 。这是否有意义?



想想这样。你有一大群人在不同的线路等待,每一行编号为1-10。你可以选择你希望每个人等待的行(通过每行同步),或者如果你不使用 @synchronized ,你可以直接跳到前面和跳过所有的行。第1行中的人不必等待第2行中的人完成,但第1行中的人不得不等待他们前面的每个人完成。


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.

解决方案

@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.

这篇关于@synchronized是否保证线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆