Objective-C中不同方式实现锁
2015-10-22 22:40
453 查看
为什么需要使用锁,当然熟悉多线程的你,自然不会对它觉得陌生。
那你在代码中是否很好的使用了锁的机制呢?你又知道几种实现锁的方法呢?今天一起来探讨一下Objective-C中几种不同方式实现的锁,在这之前我们先构建一个测试用的类,假想它是我们的一个共享资源,method1与method2是互斥的,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | @implementation TestObj - (void)method1 { NSLog(@"%@",NSStringFromSelector(_cmd)); } - (void)method2 { NSLog(@"%@",NSStringFromSelector(_cmd)); } @end |
1 2 3 4 5 6 7 8 9 10 11 12 1314 | //主线程中 TestObj *obj = [[TestObj alloc] init]; NSLock *lock = [[NSLock alloc] init]; //线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [lock lock]; [obj method1]; sleep(10); [lock unlock]; }); //线程2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(1);//以保证让线程2的代码后执行 [lock lock]; [obj method2]; [lock unlock]; }); |
NSLock是Cocoa提供给我们最基本的锁对象,这也是我们经常所使用的,除lock和unlock方法外,NSLock还提供了tryLock和lockBeforeDate:两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),刚并不会阻塞线程,并返回NO。lockBeforeDate:方法会在所指定Date之前尝试加锁,如果在指定时间之前都不能加锁,则返回NO。
2.使用synchronized关键字构建的锁
当然在Objective-C中你还可以用@synchronized指令快速的实现锁:
1 2 3 4 5 6 7 8 9 10 11 12 1314 | //主线程中 TestObj *obj = [[TestObj alloc] init]; //线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @synchronized(obj){ [obj method1]; sleep(10); } }); //线程2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(1); @synchronized(obj){ [obj method2]; } }); |
3.使用C语言的pthread_mutex_t实现的锁
1 2 3 4 5 6 7 8 9 10 11 12 1314 | //主线程中 TestObj *obj = [[TestObj alloc] init]; __block pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); //线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ pthread_mutex_lock(&mutex); [obj method1]; sleep(5); pthread_mutex_unlock(&mutex); }); //线程2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(1); pthread_mutex_lock(&mutex); [obj method2]; pthread_mutex_unlock(&mutex); }); |
4.使用GCD来实现的”锁”
以上代码构建多线程我们就已经用到了GCD的dispatch_async方法,其实在GCD中也已经提供了一种信号机制,使用它我们也可以来构建一把”锁”(从本质意义上讲,信号量与锁是有区别,具体差异参加信号量与互斥锁之间的区别):
1 2 3 4 5 6 7 8 9 10 11 12 1314 | //主线程中 TestObj *obj = [[TestObj alloc] init]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); //线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); [obj method1]; sleep(10); dispatch_semaphore_signal(semaphore); }); //线程2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(1); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); [obj method2]; dispatch_semaphore_signal(semaphore); }); |
Dispatch Sources
好了,以上就是我所列举了几种方式来实现锁,当然锁大多数情况下也是配合多线程一起使用的,关于多线程编程,我这儿就不赘述了。
相关文章推荐
- Xcode升级后插件失效的原理与修复办法
- IOS开发系列--Objective-C之协议、代码块、分类
- Objective 多态
- Objective-C基本语法
- OC内存管理高级
- JSONObject转换JSON--将Date转换为指定格式
- JSONObject、JSONArray
- spring mvc配置ObjectMapper忽略无法识别的字段,以及一些博客推荐
- gm: error while loading shared libraries: libpng15.so.15: cannot open shared object file: No such file or directory
- Swift and ObjectiveC Interop (Swift 与 Objective-C 之间的交互)
- Fatal error: Using $this when not in object context in 解决方法
- Objective-C学习-UILabel的使用
- Objective-C 程序设计 第六章
- 【Objective-C学习记录】01-基础概念
- Objective-C编码规范(待补充)
- Objective-C Runtime 运行时之二:成员变量与属性
- Objective-C Runtime 运行时之一:类与对象
- Objective-C Runtime 运行时之三:方法与消息
- objective-C nil,Nil,NULL 和NSNull的小结
- Implicit Object in JSP