6、dispatch_semaphore 信号量
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
- (void)showMessage;
@end
@implementation Person
- (void)showMessage
{
NSLog(@"%@, name is %@", [NSThread currentThread], self.name);
}
@end
- (void)threadSynchronized
{
// 互斥锁 @synchronized 的使用,锁定的对象为锁的唯一标识,只有标识相同时,才满足互斥。
NSLog(@"互斥锁");
Person *person = [Person new];
person.name = @"iosDev";
Person *person2 = [Person new];
person2.name = @"devZhang";
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(person) {
[person showMessage];
[NSThread sleepForTimeInterval:3]; // 线程休眠3秒
}
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(person) {
[person showMessage];
}
});
// 线程C
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(person2) {
[person2 showMessage];
}
});
}
2018-03-07 14:43:43.972 DemoThread[1905:201544] {number = 9, name = (null)}, name is iosDev
2018-03-07 14:43:43.972 DemoThread[1905:201556] {number = 10, name = (null)}, name is devZhang
2018-03-07 14:43:46.974 DemoThread[1905:194520] {number = 11, name = (null)}, name is iosDev
- (void)threadNSLock
{
// 互斥锁 NSLock 的使用,一个线程的执行需要等待另一个线程解锁后才开始。锁定(lock)和解锁(unLock)必须配对使用。
NSLog(@"互斥锁");
Person *person = [Person new];
person.name = @"iosDev";
Person *person2 = [Person new];
person2.name = @"devZhang";
// 创建锁
NSLock *personLock = [NSLock new];
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(person) {
[personLock lock]; // 加锁
[person showMessage];
[NSThread sleepForTimeInterval:3]; // 线程休眠3秒
[personLock unlock]; // 解锁
}
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(person) {
[personLock lock]; // 加锁
[person showMessage];
[personLock unlock]; // 解锁
}
});
// 线程C
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(person2) {
[person2 showMessage];
}
});
}
2018-03-07 14:44:19.925 DemoThread[1905:201556] {number = 10, name = (null)}, name is iosDev
2018-03-07 14:44:19.925 DemoThread[1905:202091] {number = 12, name = (null)}, name is devZhang
2018-03-07 14:44:22.930 DemoThread[1905:202090] {number = 13, name = (null)}, name is iosDev
- (void)threadNSRecursiveLock
{
// 递归锁 NSRecursiveLock 的使用,在递归方法中使用递归锁,否则会造成死锁。
NSLog(@"递归锁");
Person *person = [Person new];
person.name = @"iosDev";
Person *person2 = [Person new];
person2.name = @"devZhang";
// 创建锁对象
NSRecursiveLock *personLock = [[NSRecursiveLock alloc] init];
// 创建递归方法
static void (^testCode)(int);
testCode = ^(int value) {
[personLock lock];
if (value > 0)
{
NSLog(@"递归0");
[person showMessage];
[NSThread sleepForTimeInterval:1];
testCode(value - 1);
}
[personLock unlock];
};
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
testCode(5);
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[personLock lock];
NSLog(@"递归1");
[person showMessage];
[personLock unlock];
});
}
2018-03-07 14:44:47.007 DemoThread[1905:202091] 递归0
2018-03-07 14:44:47.007 DemoThread[1905:202091] {number = 12, name = (null)}, name is iosDev
2018-03-07 14:44:48.008 DemoThread[1905:202091] 递归0
2018-03-07 14:44:48.009 DemoThread[1905:202091] {number = 12, name = (null)}, name is iosDev
2018-03-07 14:44:49.012 DemoThread[1905:202091] 递归0
2018-03-07 14:44:49.013 DemoThread[1905:202091] {number = 12, name = (null)}, name is iosDev
2018-03-07 14:44:50.016 DemoThread[1905:202091] 递归0
2018-03-07 14:44:50.017 DemoThread[1905:202091] {number = 12, name = (null)}, name is iosDev
2018-03-07 14:44:51.019 DemoThread[1905:202091] 递归0
2018-03-07 14:44:51.019 DemoThread[1905:202091] {number = 12, name = (null)}, name is iosDev
2018-03-07 14:44:52.020 DemoThread[1905:202411] 递归1
2018-03-07 14:44:52.020 DemoThread[1905:202411] {number = 14, name = (null)}, name is iosDev
- (void)threadCondition
{
// 条件锁 NSConditionLock 的使用,只有满足条件的时候才可以解锁。
NSLog(@"条件锁");
Person *person = [Person new];
person.name = @"iosDev";
Person *person2 = [Person new];
person2.name = @"devZhang";
// 创建锁对象
NSConditionLock *personLock = [[NSConditionLock alloc] init];
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[personLock lock]; // 加锁
[person showMessage];
[NSThread sleepForTimeInterval:3];
[personLock unlockWithCondition:10]; // 符合条件时解锁
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[personLock lockWhenCondition:10]; // 符合条件时加锁
[person showMessage];
[personLock unlock]; // 解锁
});
}
2018-03-07 14:45:22.072 DemoThread[1905:202412] {number = 15, name = (null)}, name is iosDev
2018-03-07 14:45:25.077 DemoThread[1905:202887] {number = 16, name = (null)}, name is iosDev
- (void)threadCMethod
{
// C语言方法实现加锁
// 互斥锁
// 互斥锁 + 条件锁
// #import
Person *person = [Person new];
person.name = @"iosDev";
Person *person2 = [Person new];
person2.name = @"devZhang";
// 创建锁对象
NSLog(@"互斥锁");
// 互斥锁
__block pthread_mutex_t personlock;
pthread_mutex_init(&personlock, NULL);
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&personlock); // 加锁
[person showMessage];
[NSThread sleepForTimeInterval:3];
pthread_mutex_unlock(&personlock); // 解锁
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&personlock);
[person showMessage];
pthread_mutex_unlock(&personlock);
});
NSLog(@"互斥锁 + 条件锁");
// 互斥锁 + 条件锁
__block pthread_cond_t personCodition;
pthread_cond_init(&personCodition, NULL);
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&personlock); // 加锁
pthread_cond_wait(&personCodition, &personlock); // 条件锁
[person showMessage];
pthread_mutex_unlock(&personlock); // 解锁
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&personlock);
[person showMessage];
pthread_cond_signal(&personCodition); // 条件锁
[NSThread sleepForTimeInterval:3];
pthread_mutex_unlock(&personlock);
});
}
2018-03-07 14:46:07.545 DemoThread[1905:202888] {number = 17, name = (null)}, name is iosDev
2018-03-07 14:46:10.548 DemoThread[1905:203469] {number = 18, name = (null)}, name is iosDev
2018-03-07 14:46:10.548 DemoThread[1905:203471] {number = 19, name = (null)}, name is iosDev
2018-03-07 14:46:13.552 DemoThread[1905:203470] {number = 20, name = (null)}, name is iosDev
- (void)threadGCD
{
// 使用 GCD 实现 “ 锁 ” (信号量) GCD提供一种信号的机制,使用它我们可以创建“锁”(信号量和锁是有区别的,具体请自行百度)。
Person *person = [Person new];
person.name = @"iosDev";
Person *person2 = [Person new];
person2.name = @"devZhang";
// 创建并设置信量
dispatch_semaphore_t personGCD = dispatch_semaphore_create(1);
// 线程A
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(personGCD, DISPATCH_TIME_FOREVER); // 等待信号
[person showMessage];
[NSThread sleepForTimeInterval:3];
dispatch_semaphore_signal(personGCD); // 发送信号
});
// 线程B
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(personGCD, DISPATCH_TIME_FOREVER); // 等待信号
[person showMessage];
dispatch_semaphore_signal(personGCD); // 发送信号
});
}
2018-03-07 14:46:41.194 DemoThread[1905:203472] {number = 21, name = (null)}, name is iosDev
2018-03-07 14:46:44.194 DemoThread[1905:203982] {number = 22, name = (null)}, name is iosDev