iOS/Mac开发中各种锁的使用
来源:互联网 发布:comtrade数据库 编辑:程序博客网 时间:2024/06/08 00:18
- NSRecursiveLock递归锁
所谓递归锁,就是在同一线程上该锁是可重入的,它对于不同线程相当于普通的互斥锁。NSRecursiveLock类定义的锁可以在同一线程多次lock,而不会造成死锁。递归锁会跟踪它被多少次lock。每次成功的lock都必须平衡调用unlock操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得。
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];//开一个线程dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ static void (^RecursiveMethod)(int); RecursiveMethod = ^(int value) { [lock lock]; //启动递归锁 if (value > 0) { NSLog(@"value = %d", value); sleep(2); RecursiveMethod(value - 1); } [lock unlock]; //关闭递归锁 }; RecursiveMethod(5); });//再开一个线程dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(2); //判断当前锁的状态 BOOL flag = [lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]; if (flag) { NSLog(@"lock before date"); [lock unlock]; } else { NSLog(@"fail to lock before date"); } });
代码分析:第一个异步dispatch创建了一个新的线程,并加入了递归锁,此时,在第二个异步dispatch创建的新线程中,判断当前的递归锁的状态。
2. NSConditionLock条件锁
普通的互斥锁和递归锁都只考虑锁和解锁的问题,这样的锁无法满足多线程对访问共享资源的各种需求。因此,条件锁(NSConditionLock)的出现可以解决多线程技术中需要满足特定条件才能解开某些锁的场景。
//主线程中NSConditionLock *conditionLock = [[NSConditionLock alloc] init];//异步线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ for (int i=0;i<=2;i++) { //创建一个不需要条件的锁 [conditionLock lock]; NSLog(@"thread1:%d",i); sleep(2); [conditionLock unlockWithCondition:i]; } });//异步线程2dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //设置一个条件锁,需要对应的unlockWithCondition:2才能解开 [conditionLock lockWhenCondition:2]; NSLog(@"thread2"); [conditionLock unlock]; });
代码分析:异步线程1创建了一个没有开锁条件的条件锁,而异步线程2并发的创建了一个开锁条件为2的条件锁,当线程1中的循环变量i=2时,线程2中的条件锁被解开。
3. NSDistributedLock分布式锁
对于多个进程或多个程序之间需要构建互斥的场景时,使用上述多线程间的锁就无法满足需求。此时,需要使用到分布式锁。分布式锁是通过文件系统实现的,它不继承自NSLock,因而也没有实现lock方法,但它提供了tryLock,unlock,breakLock等方法,如果需要lock,则必须自己实现一个trylock的轮询。
应用A:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{//进程间互斥所用的锁NSDistributedLock *lock = [[NSDistributedLock alloc] initWithPath:@"/Users/mac/Desktop/earning__"]; [lock breakLock]; [lock tryLock]; sleep(10); [lock unlock]; NSLog(@"appA: OK"); });
应用B:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSDistributedLock *lock = [[NSDistributedLock alloc] initWithPath:@"/Users/mac/Desktop/earning__"]; while (![lock tryLock]) { NSLog(@"appB: waiting"); sleep(1); } [lock unlock]; NSLog(@"appB: OK"); });
1 0
- iOS/Mac开发中各种锁的使用
- iOS开发用到的Mac系统资源库中各种文件的路径
- IOS开发中遇到的各种问题
- iOS开发中各种关键字的区别
- iOS开发中各种关键字的区别
- iOS开发:使用UIAlertController的各种姿势
- 探讨iOS开发中各种锁
- iOS中各种控件的使用
- ios中各种插件的使用
- 开发中各种对话框的使用
- iOS 开发中各种尺寸
- iOS开发50-iOS Mac OS X Spark的使用
- iOS开发51-iOS Mac OS X Adium的使用
- 开发中遇到的Mac使用问题
- ios开发中各种版本、设备的区分
- IOS开发中遇到的各种问题以及解决方案集锦
- IOS开发中遇到的各种问题以及解决方案集锦
- ios开发中遇到的各种错(一)
- String,StringBuffer与StringBuilder的区别?
- 查找组成一个偶数最接近的两个素数
- 多台Mac用一个开发者帐号共同开发的方法(已解决)
- 斐波那契数列 大数加法hdu1316
- 怎么在div中创建子元素,删除子元素,删除所有的子元素
- iOS/Mac开发中各种锁的使用
- Android WiFi--系统架构(一)
- iOS -- UI常用组件总结
- 一个平庸程序员的自白
- java io流
- 我来了
- 黑马程序员——Java基础---数组与集合之间转换
- C++嵌入Python程序(二):参数传入及返回
- HDU 1316 How Many Fibs?