多线程之线程锁的使用
2015-07-21 22:13
344 查看
Object-C 多线程中锁的使用-NSLock
(2013-05-05 20:22:44)转载▼
标签: nslocknslockingsynchronizedobject-c加锁xcode | 分类: 帮助文档 |
//线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @synchronized(_myLockObj){ [obj1 method1]; sleep(30); } @synchronized(obj1){
} }); //线程2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(1); @synchronized(_myLockObj){ [obj1 method2]; } }); }这样,就会起到锁的作用,线程2会等待线程1执行完成@synchronized(obj){}块后,在执行。从而起到锁的作用。
2.使用NSLock方式
先贴一个例子:
1. TestObj.h
@interface TestObj : NSObject- (void)method1;- (void)method2;@end2. TestObj.m
#import "TestObj.h"
@implementation TestObj
- (void)method1{ NSLog(@"%@",NSStringFromSelector(_cmd)); NSLog(@"Current thread = %@", [NSThread currentThread]); NSLog(@"Main thread = %@", [NSThread mainThread]);}
- (void)method2{ NSLog(@"%@",NSStringFromSelector(_cmd)); NSLog(@"Current thread = %@", [NSThread currentThread]); NSLog(@"Main thread = %@", [NSThread mainThread]); }
@end3.在需要锁的视图控制器中,申明锁对象。
TestObj *obj = [[TestObj alloc] init]; NSLock *lock = [[NSLock alloc] init];
4.多线程状态下,锁操作
//线程1 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [lock lock]; [obj method1]; sleep(30); [lock unlock]; }); //线程2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ sleep(5);//以保证让线程2的代码后执行 [lock lock]; [obj method2]; [lock unlock]; });5.总结
使用时,基本方法就是:[lock lock];[obj yourMethod];[lock unlock];
我们称[obj yourMethod]为“关键部分”。NSLock的执行原理:某个线程A调用lock方法。这样,NSLock将被上锁。可以执行“关键部分”,完成后,调用unlock方法。如果,在线程A 调用unlock方法之前,另一个线程B调用了同一锁对象的lock方法。那么,线程B只有等待。直到线程A调用了unlock。
最后,还是看看API中对NSLock的一些说明
@protocol NSLocking
lock 方法- (void)lock获得锁
unlock 方法- (void)unlock释放锁
@interface NSLock
lockBeforeDate: 方法- (BOOL)lockBeforeDate:(NSDate *)limit在指定的时间以前得到锁。YES:在指定时间之前获得了锁;NO:在指定时间之前没有获得锁。该线程将被阻塞,直到获得了锁,或者指定时间过期。
tryLock 方法- (BOOL)tryLock视图得到一个锁。YES:成功得到锁;NO:没有得到锁。
setName: 方法- (void)setName:(NSString *)newName为锁指定一个Name
name 方法- (NSString *)name返回锁指定的Name
三、使用GCD中dispatch_semaphore_t和dispatch_semaphore_wait
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); });关于GCD中dispatch_semaphore_create和dispatch_semaphore_wait的使用。请参见我的另一篇博客:
GCD(Grand Central Dispatch)和Block 使用-浅析
相关文章推荐
- 痛并快乐着
- 协程 及 Libco 介绍
- JDBC连接MySql数据库
- Maven实战(坐标和依赖)
- 【树形dp】hdu 1011 Starship Troopers
- Linux僵尸进程的解决
- Github for Windows
- Opencv3.0.0 vs2012 win7配置
- Linux下安装opencv
- 2015第30周二
- Ubuntu系统安装配置Pintos和Bochs
- 13. JavaSE-多态 & 内部类
- 第62讲scala 隐式参数实例解析
- 广搜专题-1002
- 2015.7.21 第十课 课程重点(jq选择器:id、类、标签、奇偶、eq、nth-child、子元素、属性、包含、位置、过滤)
- elasticsearch参数详解
- [Spring MVC] - JSP + Freemarker视图解释器整合(转)
- C语言输入下标数,把下标值改成0并放到最后,再依次打印。
- C#如何获取当前项目的目录,并以当前为根进行修改
- spring事务管理-摘抄