一、NSLock
加锁lock
解锁unlock
NSLock *lock = [[NSLock alloc]init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程一");
sleep(10);
[lock unlock];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([lock tryLock]) {
NSLog(@"线程二");
sleep(1);
[lock unlock];
}else{
NSLog(@"测试加锁失败");
}
});
二、NSConditionLock条件锁
跟NSLock类似,多了个条件锁Condition
//主线程中
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:0];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lockWhenCondition:1];
NSLog(@"线程1");
sleep(2);
[lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(5);//以保证让线程2的代码后执行
if ([lock tryLockWhenCondition:0]) {
NSLog(@"线程2");
[lock unlockWithCondition:2];
NSLog(@"线程2解锁成功");
} else {
NSLog(@"线程2尝试加锁失败");
}
});
//线程3
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(2);//以保证让线程2的代码后执行
if ([lock tryLockWhenCondition:2]) {
NSLog(@"线程3");
[lock unlock];
NSLog(@"线程3解锁成功");
} else {
NSLog(@"线程3尝试加锁失败");
}
});
//线程4
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(3);//以保证让线程2的代码后执行
if ([lock tryLockWhenCondition:2]) {
NSLog(@"线程4");
[lock unlockWithCondition:1];
NSLog(@"线程4解锁成功");
} else {
NSLog(@"线程4尝试加锁失败");
}
});
三、递归锁NSRecursiveLock
实际是一个同步锁
#import
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
static void (^RecursiveBlock)(int);
RecursiveBlock = ^(int value) {
[lock lock];
if (value > 0) {
NSLog(@"value:%d", value);
sleep(3);
RecursiveBlock(value - 1);
}
[lock unlock];
};
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"开始睡觉");
sleep(2);
NSLog(@"睡了2秒");
sleep(4);
NSLog(@"睡了4秒");
});
NSLog(@"递归一开始");
RecursiveBlock(5);
NSLog(@"递归一完成");
sleep(1);
RecursiveBlock(3);
});
四、线程、锁判断NSCondition
__block NSMutableArray *products = [NSMutableArray array];
NSCondition *condition = [NSCondition new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"线程一开始");
[condition lock];
while (products.count<1) {
NSLog(@"线程一等待");
//线程等待
[condition wait];
}
NSLog(@"线程一执行");
[products removeObjectAtIndex:0];
[condition unlock];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
NSLog(@"线程二");
[condition lock];
[products addObject:@1];
//唤醒等待的线程
[condition signal];
[condition unlock];
});
五、## @synchronized
@synchronized (self) {
//some code
}
//等价于
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLock *lock = [NSLock new];
[lock lock];
//some code
[lock unlock];
});
//等价于
NSString *test = @"test";
id synchronizeTarget = (id)test;
@try {
objc_sync_enter(synchronizeTarget);
test = nil;
} @finally {
objc_sync_exit(synchronizeTarget);
}
六、信号量dispatch_semaphore_t
dispatch_semaphore_t signal = dispatch_semaphore_create(0);
dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 9 * NSEC_PER_SEC);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(3);
NSLog(@"signal");
dispatch_semaphore_signal(signal);
});
NSLog(@"wait");
dispatch_semaphore_wait(signal, overTime);
NSLog(@"end");
七、互坼锁mutex
#import
#import
static pthread_mutex_t theLock;
- (void)example5 {
/*
PTHREAD_MUTEX_NORMAL 缺省类型,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后先进先出原则获得锁。
PTHREAD_MUTEX_ERRORCHECK 检错锁,如果同一个线程请求同一个锁,则返回 EDEADLK,否则与普通锁类型动作相同。这样就保证当不允许多次加锁时不会出现嵌套情况下的死锁。
PTHREAD_MUTEX_RECURSIVE 递归锁,允许同一个线程对同一个锁成功获得多次,并通过多次 unlock 解锁。
PTHREAD_MUTEX_DEFAULT 适应锁,动作最简单的锁类型,仅等待解锁后重新竞争,没有等待队列。
*/
pthread_mutex_init(&theLock, NULL);
//设置类型
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&theLock, &attr);
pthread_mutexattr_destroy(&attr);
pthread_t thread;
pthread_create(&thread, NULL, threadMethord1, NULL);
pthread_t thread2;
pthread_create(&thread2, NULL, threadMethord2, NULL);
}
void *threadMethord1() {
pthread_mutex_lock(&theLock);
printf("线程1\n");
sleep(2);
pthread_mutex_unlock(&theLock);
printf("线程1解锁成功\n");
return 0;
}
void *threadMethord2() {
sleep(1);
pthread_mutex_lock(&theLock);
printf("线程2\n");
pthread_mutex_unlock(&theLock);
printf("线程2解锁成功\n");
return 0;
}
八、自旋锁OSSpinLock (因为线程安全问题,iOS 10.0以后废弃了,取而代之的是互斥锁os_unfair_lock_lock,类似于pthread_mutex)
#import
__block OSSpinLock oslock = OS_SPINLOCK_INIT;
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"线程1 准备上锁");
OSSpinLockLock(&oslock);
sleep(4);
NSLog(@"线程1");
OSSpinLockUnlock(&oslock);
NSLog(@"线程1 解锁成功");
NSLog(@"--------------------------------------------------------");
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"线程2 准备上锁");
OSSpinLockLock(&oslock);
NSLog(@"线程2");
OSSpinLockUnlock(&oslock);
NSLog(@"线程2 解锁成功");
});