@synchronized
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"线程1 开始");
@synchronized (self) {
sleep(3);
NSLog(@"线程1 结束");
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"线程2 开始");
@synchronized (self) {
sleep(1);
NSLog(@"线程2 结束");
}
});
dispatch_semaphore
dispatch_semaphore_t signal = dispatch_semaphore_create(1);
dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(signal, overTime);
NSLog(@"线程1 开始");
sleep(2);
NSLog(@"线程1 结束");
dispatch_semaphore_signal(signal);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(signal, overTime);
NSLog(@"线程2 开始");
sleep(1);
NSLog(@"线程2 结束");
dispatch_semaphore_signal(signal);
});
-
dispatch_semaphore_wait
会使信号量减1,如果信号量的值小于0,就阻塞当前线程直到超时才继续执行。
-
dispatch_semaphore_signal
使信号量加1,如果之前的信号量小于0,那么会唤醒正在由dispatch_semaphore_wait
等待的线程。
NSLock
NSLock *lock = [[NSLock alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程1 开始");
sleep(2);
NSLog(@"线程1 结束");
[lock unlock];
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([lock tryLock]) {
NSLog(@"锁可用");
[lock unlock];
}
else {
NSLog(@"锁不可用");
}
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:3];
if ([lock lockBeforeDate:date]) {
NSLog(@"没有超时, 获得锁");
[lock unlock];
}
else {
NSLog(@"超时, 没有获得锁");
}
});
NSRecursiveLock
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
__block int value = 5;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
static void(^RecursiveMethod)(void);
RecursiveMethod = ^(void) {
[lock lock];
if (value > 0) {
NSLog(@"线程1 value = %d", value);
value -= 1;
sleep(1);
RecursiveMethod();
}
[lock unlock];
};
RecursiveMethod();
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程2 value = %d", value);
[lock unlock];
});
NSConditionLock
NSMutableArray *products = [NSMutableArray arrayWithArray:@[@"1", @"2", @"3"]];
NSInteger beginProduct = 1; // 开始生产, 停止消费
NSInteger haltProduct = 0; // 停止生产, 开始消费
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:beginProduct];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
[lock lockWhenCondition:beginProduct];
[products addObject:@"1"];
NSLog(@"生产了一个产品, 总量: %zi", products.count);
NSInteger status = products.count > 10 ? haltProduct : beginProduct;
[lock unlockWithCondition:status];
sleep(5);
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
[lock lockWhenCondition:haltProduct];
[products removeObjectAtIndex:0];
NSLog(@"消费了一个产品, 总量: %zi", products.count);
NSInteger status = products.count < 3 ? beginProduct : haltProduct;
[lock unlockWithCondition:status];
sleep(3);
}
});
NSCondition
NSCondition *condition = [[NSCondition alloc] init];
NSMutableArray *products = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
[condition lock];
if (products.count == 0) {
NSLog(@"等待生产");
[condition wait];
}
[products removeObjectAtIndex:0];
NSLog(@"消费了一个产品, 总量: %zi", products.count);
[condition unlock];
sleep(2);
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
[condition lock];
[products addObject:@"1"];
NSLog(@"生产了一个产品, 总量: %zi", products.count);
if (products.count > 5) {
[condition signal];
}
[condition unlock];
sleep(3);
}
});
pthread_mutex
static pthread_mutex_t lock;
pthread_mutex_init(&lock, NULL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&lock);
NSLog(@"线程1 开始");
sleep(3);
NSLog(@"线程1 结束");
pthread_mutex_unlock(&lock);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&lock);
NSLog(@"线程2 开始");
sleep(3);
NSLog(@"线程2 结束");
pthread_mutex_unlock(&lock);
});
pthread_mutex(recursive)
static pthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);
__block int value = 5;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
static void(^RecursiveMethod)(void);
RecursiveMethod = ^{
pthread_mutex_lock(&lock);
if (value > 0) {
NSLog(@"线程1 value = %d", value);
value -= 1;
sleep(2);
RecursiveMethod();
}
pthread_mutex_unlock(&lock);
};
RecursiveMethod();
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&lock);
NSLog(@"线程2 value = %d", value);
pthread_mutex_unlock(&lock);
});
OSSpinLock
static OSSpinLock lock = OS_SPINLOCK_INIT;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
OSSpinLockLock(&lock);
NSLog(@"线程1 开始");
sleep(3);
NSLog(@"线程1 结束");
OSSpinLockUnlock(&lock);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
OSSpinLockLock(&lock);
NSLog(@"线程2 开始");
sleep(3);
NSLog(@"线程2 结束");
OSSpinLockUnlock(&lock);
});
os_unfair_lock
if (@available(iOS 10.0, *)) {
static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
os_unfair_lock_lock(&lock);
NSLog(@"线程1 开始");
sleep(3);
NSLog(@"线程1 结束");
os_unfair_lock_unlock(&lock);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
os_unfair_lock_lock(&lock);
NSLog(@"线程2 开始");
sleep(3);
NSLog(@"线程2 结束");
os_unfair_lock_unlock(&lock);
});
}
参考资料
iOS中保证线程安全的几种方式与性能对比
网友评论