1.Synchronized方式
h文件
@interface testLock : NSObject{
NSString *mStr;
}
- (void)testSynchronized:(NSString *)str;
@implementation testLock
- (void)testSynchronized:(NSString *)str{
@synchronized (mStr) {
NSLog(@"testSynchronized_1,str:%@",str);
NSLog(@"testSynchronized_2,str:%@",str);
NSLog(@"testSynchronized_3,str:%@",str);
NSLog(@"testSynchronized_4,str:%@",str);
mStr = str;
}
}
main函数:
testLock *tempLock = [[testLock alloc] init:@"temp"];
[tempLock testSynchronized:@"tempLocktestSynchronized"];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[tempLock testSynchronized:@"test1testSynchronized"];
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[tempLock testSynchronized:@"test2testSynchronized"];
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[tempLock testSynchronized:@"test3testSynchronized"];
});
输出结果:
2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_1,str:tempLocktestSynchronized
2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_2,str:tempLocktestSynchronized
2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_3,str:tempLocktestSynchronized
2016-06-12 15:20:30.870 TestRuntime[5407:398185] testSynchronized_4,str:tempLocktestSynchronized
2016-06-12 15:20:30.870 TestRuntime[5407:398223] testSynchronized_1,str:test1testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398223] testSynchronized_2,str:test1testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398223] testSynchronized_3,str:test1testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398223] testSynchronized_4,str:test1testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_1,str:test2testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_2,str:test2testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_3,str:test2testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398224] testSynchronized_4,str:test2testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_1,str:test3testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_2,str:test3testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_3,str:test3testSynchronized
2016-06-12 15:20:30.871 TestRuntime[5407:398225] testSynchronized_4,str:test3testSynchronized
如果修改对应m文件的内容为:
- (void)testSynchronized:(NSString *)str{
@synchronized (mStr) {
mStr = str;
NSLog(@"testSynchronized_1,str:%@",str);
NSLog(@"testSynchronized_2,str:%@",str);
NSLog(@"testSynchronized_3,str:%@",str);
NSLog(@"testSynchronized_4,str:%@",str);
}
}
则输出为:
2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_1,str:tempLocktestSynchronized
2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_2,str:tempLocktestSynchronized
2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_3,str:tempLocktestSynchronized
2016-06-12 15:22:52.821 TestRuntime[5475:399682] testSynchronized_4,str:tempLocktestSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_1,str:test1testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_1,str:test2testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_2,str:test1testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_1,str:test3testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_2,str:test2testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_3,str:test1testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_2,str:test3testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_3,str:test3testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_3,str:test2testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399717] testSynchronized_4,str:test1testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399719] testSynchronized_4,str:test3testSynchronized
2016-06-12 15:22:52.822 TestRuntime[5475:399718] testSynchronized_4,str:test2testSynchronized
从上面的结果可以看出,在对mStr变量做锁定的时候,对mStr的值的改变的语句位置不同会造成@synchronized内部执行顺序的不一样,从输出看,只要mStr的值已经被修改,则锁就好像被释放了?~
2.NSLock
NSLock * lock = [[NSLock alloc]init];
NSMutableArray * piaos = [NSMutableArray arrayWithArray:@[@"a",@"b",@"c"]];
// 线程1
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lock lock];
NSLog(@"thread1:%@",piaos);
sleep(3);
[piaos removeObject:@"a"];
[lock unlock];
});
// 线程2
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[piaos removeObject:@"b"];
NSLog(@"thread2:%@",piaos);
});
// 线程3
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lock lock];
NSLog(@"thread3:%@",piaos);
[lock unlock];
});
输出:
2016-06-12 15:32:54.819 TestRuntime[5515:409045] thread1:(
a,
b,
c
)
2016-06-12 15:32:54.819 TestRuntime[5515:409046] thread2:(
a,
c
)
2016-06-12 15:32:57.819 TestRuntime[5515:409047] thread3:(
c
)
所有加相同锁的内容只能按照 [lock lock]以及[lock unlock]的顺序执行,对没有加锁的代码片段没有影响
3.NSConditionLock
NSConditionLock * lock = [[NSConditionLock alloc]init];
//Thread1
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (int i = 0; i< 4; i++) {
[lock lock];
NSLog(@"thread1");
[lock unlockWithCondition:i];
sleep(3);
}
});
// Thread2
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"thread2");
});
// Thread3
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lock lockWhenCondition:3];
NSLog(@"thread3");
[lock unlock];
});
// Thread4
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lock lockWhenCondition:2];
NSLog(@"thread4");
[lock unlock];
});
输出:
2016-06-12 15:34:45.145 TestRuntime[5531:411155] thread2
2016-06-12 15:34:45.145 TestRuntime[5531:411154] thread1
2016-06-12 15:34:48.146 TestRuntime[5531:411154] thread1
2016-06-12 15:34:51.146 TestRuntime[5531:411154] thread1
2016-06-12 15:34:51.146 TestRuntime[5531:411155] thread4
2016-06-12 15:34:54.148 TestRuntime[5531:411154] thread1
2016-06-12 15:34:54.148 TestRuntime[5531:411156] thread3
满足条件的时候可以lock和unlock,可以随意组合:lock ,lockWhenCondition,unlock,unlockWithCondition
4.NSRecursiveLock
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(1);
RecursiveMethod(value - 1);
}
[lock unlock];
};
RecursiveMethod(5);
});
输出:
2016-06-12 15:36:44.951 TestRuntime[5544:413127] value = 5
2016-06-12 15:36:45.955 TestRuntime[5544:413127] value = 4
2016-06-12 15:36:46.959 TestRuntime[5544:413127] value = 3
2016-06-12 15:36:47.961 TestRuntime[5544:413127] value = 2
2016-06-12 15:36:48.965 TestRuntime[5544:413127] value = 1
如果改用NSLock,发生死锁则会输出:
2016-06-12 15:38:15.877 TestRuntime[5558:414854] value = 52016-06-12 15:38:16.879 TestRuntime[5558:414854] *** -[NSLock lock]: deadlock ('(null)')
2016-06-12 15:38:16.880 TestRuntime[5558:414854] *** Break on _NSLockError() to debug.
NSRecursiveLock会跟踪它被多少次lock。每次成功的lock都必须平衡调用unlock操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得;
5.NSCondition
NSCondition * lock = [[NSCondition alloc]init];
NSMutableArray * piaos = [NSMutableArray arrayWithArray:@[@"1",@"2",@"3"]];
// Thread1
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lock lock];
NSLog(@"Thread1,lock done");
[lock wait];
NSLog(@"Thread1,wait done");
[lock unlock];
NSLog(@"Thread1,unlock done");
});
// Thread2
dispatch_async(dispatch_get_global_queue(0, 0), ^{
static void (^clearTheObj)(NSMutableArray * array);
clearTheObj = ^(NSMutableArray * array){
NSLog(@"%lu",(unsigned long)array.count);
if ([array count]>0) {
[array removeObjectAtIndex:0];
}else{
[lock signal];
NSLog(@"Thread2,signal done");
return;
}
sleep(1);
clearTheObj(array);
};
[lock lock];
NSLog(@"Thread2,lock done");
clearTheObj(piaos);
NSLog(@"Thread2,clearTheObj done");
[lock unlock];
NSLog(@"Thread2,unlock done");
});
输出:
2016-06-12 15:39:37.653 TestRuntime[5571:415857] Thread1,lock done
2016-06-12 15:39:37.653 TestRuntime[5571:415858] Thread2,lock done
2016-06-12 15:39:37.653 TestRuntime[5571:415858] 3
2016-06-12 15:39:38.657 TestRuntime[5571:415858] 2
2016-06-12 15:39:39.658 TestRuntime[5571:415858] 1
2016-06-12 15:39:40.658 TestRuntime[5571:415858] 0
2016-06-12 15:39:40.658 TestRuntime[5571:415858] Thread2,signal done
2016-06-12 15:39:40.658 TestRuntime[5571:415858] Thread2,clearTheObj done
2016-06-12 15:39:40.658 TestRuntime[5571:415858] Thread2,unlock done
2016-06-12 15:39:40.658 TestRuntime[5571:415857] Thread1,wait done
2016-06-12 15:39:40.658 TestRuntime[5571:415857] Thread1,unlock done
说明,thread1在lock之后,执行了wait,然后会暂停执行,随后thread2获取到线程操作权;
知道thread2 执行了signal,thread1才会停止wait,并且继续往下执行~