[英]@synchronized and dispatch_async
我想做的是使用@synchronized
指令来保护单个对象不被多个线程一次访问。 我还想通过在每次修改后将其写入磁盘来持久存储该单例对象,因为尽我最大努力不丢失对该对象的任何更改非常重要。
现在我知道你们中很多人可能会说不要这样做; 需要太长时间 这不是一个好习惯,等等。是的,我知道这一点。 这更像是“将会发生什么?” 题。
因此,每当我去修改单例对象时,我都会将修改代码放在@synchronized
块中,然后将该对象写入磁盘。 我当时的想法是使用dispatch_async
在类似这样的单独线程上写对象:
//singleton object
id dataStructure;
@synchronized(lockObject)
{
//code that modifies singleton object
//not important
//sharedFileQueue is a SERIAL queue
dispatch_async([self sharedFileQueue], ^(void){
NSError * err;
NSData * plist = [NSPropertyListSerialization dataWithPropertyList:dataStructure
format:NSPropertyListBinaryFormat_v1_0
options:0 error:&err];
//url to somewhere
NSURL * url;
BOOL success = [plist writeToURL:url atomically:YES];
});
}
因此,我对@synchronized
理解是,一次只有一个线程可以执行该代码块。 我对dispatch_async
理解有些模糊,但是我认为这会将块提交到调度队列以异步执行并立即返回。 这意味着,如果另一个线程来通过我@synchronized
块,而dataStructure
仍然被写入到磁盘,它只是提出另一块运行并写入新修改的dataStructure
到磁盘上,但不会开始,直到第一个dataStructure
被写入到磁盘。
我在想这个吗? 还会将原子设置更改为YES
或NO
还是将我的调度队列的序列化确保不会将多个线程同时写入此文件?
谢谢!
调度队列本身是线程安全的。 换句话说,您可以从系统上的任何线程将任务提交到调度队列,而无需先获取锁或同步对该队列的访问。
//singleton object
id dataStructure;
@synchronized(lockObject)
{
//code that modifies singleton object
//not important
id dataStructureToWrite = [dataStructure copy];
//sharedFileQueue is a SERIAL queue
dispatch_async([self sharedFileQueue], ^(void){
NSError * err;
NSData * plist = [NSPropertyListSerialization dataWithPropertyList:dataStructureToWrite
format:NSPropertyListBinaryFormat_v1_0
options:0 error:&err];
//url to somewhere
NSURL * url;
BOOL success = [plist writeToURL:url atomically:YES];
});
}
您至少需要同步锁对象上的写入。 这是因为异步块在@synchronized{ ... }
的上下文之外执行。 这意味着在写入数据时,其他某些事情可能会更改数据,这可能导致逻辑上的不一致。
您可能还需要某种机制来检查对象自上次写入以来是否已被修改。 否则,您会发现自己在执行不必要的IO操作。 例如
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.