熟悉多线程开发的同学对锁肯定不陌生,但是OC中如何实现锁呢?给大家科普一下。 

 首先构建一个测试用的类,假想它是我们的一个共享资源,method1与method2是互斥的,代码如下:

@implementation TestObj
- (void)method1
{
NSLog(@"%@",NSStringFromSelector(_cmd));
}
- (void)method2
{
NSLog(@"%@",NSStringFromSelector(_cmd));
}
@end

1.使用NSLock实现的锁

 

//主线程中
TestObj *obj = [[TestObj alloc] init];
NSLock *lock = [[NSLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
[lock lock];
[obj method1];
sleep();
[lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
sleep();//以保证让线程2的代码后执行
[lock lock];
[obj method2];
[lock unlock];
});

2.使用synchronized关键字构建的锁

当然在Objective-C中你还可以用@synchronized指令快速的实现锁:

//主线程中
TestObj *obj = [[TestObj alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
@synchronized(obj){
[obj method1];
sleep();
}
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
sleep();
@synchronized(obj){
[obj method2];
}
});

@synchronized指令使用的obj为该锁的唯一标识,只有当标识相同时,才为满足互斥,如果线程2中的@synchronized(obj)改为@synchronized(other),刚线程2就不会被阻塞,@synchronized指令实现锁的优点就是我们不需要在代码中显式的创建锁对象,便可以实现锁的机制,但作为一种预防措施,@synchronized块会隐式的添加一个异常处理例程来保护代码,该处理例程会在异常抛出的时候自动的释放互斥锁。所以如果不想让隐式的异常处理例程带来额外的开销,你可以考虑使用锁对象。

3.使用GCD来实现的”锁”
以上代码构建多线程我们就已经用到了GCD的dispatch_async方法,其实在GCD中也已经提供了一种信号机制,使用它我们也可以来构建一把”锁”(从本质意义上讲,信号量与锁是有区别,具体差异参加信号量与互斥锁之间的区别):

//主线程中
TestObj *obj = [[TestObj alloc] init];
dispatch_semaphore_t semaphore = dispatch_semaphore_create();
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[obj method1];
sleep();
dispatch_semaphore_signal(semaphore);
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
sleep();
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[obj method2];
dispatch_semaphore_signal(semaphore);
});

参考资料:http://www.tanhao.me/pieces/616.html/

OC中实现锁的更多相关文章

  1. 深入理解 iOS 开发中的锁

    来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大 ...

  2. OC 中的 weak 属性是怎么实现的?

    OC 中的 weak 属性是怎么实现的,为什么在对象释放后会自动变成 nil?本文对这个问题进行了一点探讨.环境 mac OS Sierra 10.12.4 objc709参考答案 搜索后发现runt ...

  3. OC中并发编程的相关API和面临的挑战

    OC中并发编程的相关API和面临的挑战(1) 小引 http://www.objc.io/站点主要以杂志的形式,深入挖掘在OC中的最佳编程实践和高级技术,每个月探讨一个主题,每个主题都会有几篇相关的文 ...

  4. Android中应用锁的实现之账号盗取

    一.前言 前几天忙着公司的活,最近又可以歇歇了,休息不能不做事呀?今天就来研究一下Android中应用锁的实现.应用锁顾名思义就是对app进行加密,在打开app的时候需要输入指定的密码才能打开应用. ...

  5. Hibernate中的锁机制

    锁机制:是数据库为了保证数据的一致性<一个事务的各种操作不相互影响>而使各种共享资源在被并发访问访问变得有序所设计的一种规则,用来保证在当前用户进行操作数据的时候其他的用户不能对同一数据进 ...

  6. OC中加载html5调用html方法和修改HTML5内容

    1.利用webView控件加载本地html5或者网络上html5 2.设置控制器为webView的代理,遵守协议 3.实现代理方法webViewDidFinishLoad: 4.在代理方法中进行操作H ...

  7. 谈谈iOS中的锁

    1 前言 近日工作不是太忙,刚好有时间了解一些其他东西,本来打算今天上午去体检,但是看看天气还是明天再去吧,也有很大一个原因:就是周六没有预约上!闲话少说,这里简单对锁来个简单介绍分享. 2 目录 第 ...

  8. java中的继承与oc中的继承的区别

    为什么要使用继承? 继承的好处: (1)抽取出了重复的代码,使代码更加灵活 (2)建立了类和类之间的联系 继承的缺点: 耦合性太强 OC中的继承 1.OC中不允许子类和父类拥有相同名称的成员变量名:( ...

  9. Swift: 比较Swift中闭包传值、OC中的Block传值

    一.介绍 开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值.在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包 ...

随机推荐

  1. dokuwiki工具栏添加换行回车快捷键与按钮

    需求 dokuwiki的语法要求以 \\ 为换行符(\\后面必须有1个空格).编辑器有快捷键.快捷键说明如下.https://www.dokuwiki.org/start?id=zh-tw:acces ...

  2. Ubuntu环境如何上传项目到GitHub网站?

    http://blog.csdn.net/ajianyingxiaoqinghan/article/details/70544159

  3. What is the difference between WinRT, UWP and WPF?

    在学习UWP的过程中确实有这个迷惑,在此分享一下. UWP (Universal Windows platform), Metro and WinRT are all result of Micros ...

  4. pandas读取csv数据时设置index

    比如读取数据时想把第一列设为index,那么只需要简单的 pd.read_csv("new_wordvecter.csv",index_col=[0]) 这里index_col可以 ...

  5. ionic npm安装报错 no such file ,解决办法

    Install the latest version of NodeJS from their website (e.g. 6.X.X). Open the Node.js command promp ...

  6. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):2. 实现绘图功能

    1. 理解 kivy 坐标系统 上一节中,咪博士带大家实现了画板程序的基础框架,以及一个基本的自定义窗口部件(widget).在上一节的末尾,咪博士留了一道关于 kivy 坐标系统的思考题给大家.通过 ...

  7. Java之资源文件读取

    ClassLoaderWrapper.java package org.utils.resource; import java.io.InputStream; import java.net.URL; ...

  8. quartz.net 3.x版本如何通过xml文件进行Job配置

    在2.x版本中,我们可以简单的在quartz.config文件中通过以下Xml配置方式来注册相应的Job以及触发器 quartz.plugin.xml.type = Quartz.Plugin.Xml ...

  9. python day4 ---------------文件的基本操作

    1.能调用方法的一定是对象,比如数值.字符串.列表.元组.字典,甚至文件也是对象,Python中一切皆为对象. str1 = 'hello' str2 = 'world' str3 = ' '.joi ...

  10. MT【108】线面角最小

    评:线面角最小,在此类最值中经常用到,作为选择填空可以投机.