浅谈iOS @synchronized 锁用法
接触开发稍微深一点的人都应该知道锁的概念,所谓锁,就是在操作数据的时候,为了防止多个操作同时操作一个数据导致数据的错乱或者非即时而采用的一种规避手段。
尤其在使用多线程进行开发时,由于多个线程的操作可能会同时对某个数据进行操作,可能是读也可能是写,如果不加以处理,那么可能在一个线程读的时候另一个线程去写,读的线程得到的数据就可能不是最新的数据,或者两个线程同时对数据进行修改,导致一些不可预知的错乱。
这时候就应该加一道锁,在A线程操作数据的时候,将数据给锁住,锁住的意思也就是不允许其他线程来操作这个数据,想操作的都得进行等待,直到 A操作完了,才将锁给打开,这时才允许其他线程排队进行操作。
说到锁,还有个概念不得不说,那就是信号量,信号量是用来控制加锁解锁的,比如说一个变量,为0表示当前无人操作,为1表示当前有人操作,那么当一个线程要操作时,先看这个信号量是不是0,是0就可以操作, 是1就得等待,这事一种信号量的形式,还有多种形式。
在iOS开发中多线程也是经常用到的东西,因此对于一些关键的代码就有必要加锁。iOS 中加锁有多种方式,比如:
- NSLock
- dispatch_semaphore_wait
- @synchronized
本文要说的就是最后一种 @synchronized 的用法。其实 @synchronized 用法很简单,首先 @synchronized() 小括号内需要一个参数,这个参数就表示信号量。这个参数可以是任何对象,包括 self,或者是自定义的信号量。针对不同的操作应该定义不同的信号量。
@synchronized() {...} 大括号中就是要加锁执行的代码,代码会操作一些数据。当开始执行代码时,意味着当前线程对其加锁了,当代码执行完后,自动解锁,其他线程才允许执行此段代码。
下面是用 self 作为信号量来加锁的示例,也就是在当前实例中对此代码块操作要加锁:
-(void)importantMethod
{
@synchronized(self)
{
// 关键代码;
}
}
下面是使用自定义的信号量来加锁的示例:
-(void)importantMethod
{
Account *account = [AccountaccoutFromString :[accountFiled stringValue]];
//获取信号量
id accountSemaphore = [account semaphore];
@synchronized(accountSemaphore)
{
//关键代码
}
}
值得一提的是这个加锁机制是支持递归的,如果加锁的代码在当前线程中递归调用自身,那么会持续保持加锁状态,其余线程还是访问不了,只有当递归完成全部执行完后,或者出错报异常退出后,锁才会解开,释放信号量,其余线程才允许操作此段代码块。
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十