在多线程的编程环境中,锁的使用必不可少!html
因而,今天来总结一下为共享资源加锁的操做方法。编程
1、使用synchronized方式多线程
//线程1async
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{spa
@synchronized (_myLockObj){.net
[obj1 method1];线程
sleep(30);orm
}htm
@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;
@end
2. 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]);
}
@end
3.在须要锁的视图控制器中,申明锁对象。
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
3、使用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 使用-浅析
但愿对你有所帮助!