方法一:用NSLock
TestObj *obj = [[TestObj alloc] init];
//線程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的代碼后執(zhí)行
[lock lock];
[obj method2];
[lock unlock];
});
方法二:用@synchronized
TestObj *obj = [[TestObj alloc] init];
//線程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized (obj) {
[obj method1];
}
sleep(30);
});
//線程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(5);//以保證讓線程2的代碼后執(zhí)行
@synchronized (obj) {
[obj method2];
}
});
方法三:用GCD的dispatch_semaphore_t和dispatch_semaphore_wait
- dispatch_semaphore_create(num),這里的num相當于古代將軍發(fā)的令牌數(shù)目,如果num是1,表示可以分配給一個將領(lǐng)去執(zhí)行任務(wù),實例代碼代碼如下:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"method1");
sleep(10);
dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"method2");
dispatch_semaphore_signal(semaphore);
});
這里dispatch_semaphore_create(1)創(chuàng)建的是一個令牌,所以會先執(zhí)行method1任務(wù),然后等待10秒后發(fā)送一個信號(dispatch_semaphore_signal(semaphore))使信號量+1,再執(zhí)行method2任務(wù)
- num如果是0,沒有令牌,就立即執(zhí)行dispatch_semaphore_wait方法:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"method1");
sleep(10);
dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"method2");
dispatch_semaphore_signal(semaphore);
});
這里只執(zhí)行到dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);,永遠不會執(zhí)行NSLog(@"method1")和下面的method2方法
- num如果是2,分配2個令牌,使得下面兩個進程都可以執(zhí)行:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"method1");
sleep(10);
dispatch_semaphore_signal(semaphore);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"method2");
dispatch_semaphore_signal(semaphore);
});
方法三:用pthread_mutex互斥鎖
- 初始化
導(dǎo)入#import <pthread.h>
@interface XYThread ()
{
pthread_mutex_t mutex; //聲明pthread_mutex_t的結(jié)構(gòu)
}
@end
//在viewDidLoad里初始化
- (void)viewDidLoad {
[super viewDidLoad];
pthread_mutex_init(&mutex, NULL);
}
- 加鎖and解鎖
//加鎖
pthread_mutex_lock(&mutex);
/*你的代碼*/
//解鎖
pthread_mutex_unlock(&mutex);
- 釋放鎖
- (void)dealloc{
pthread_mutex_destroy(&mutex); //釋放該鎖的數(shù)據(jù)結(jié)構(gòu)
}
針對函數(shù)遞歸調(diào)用的情況,可以使用遞歸鎖
- (void)viewDidLoad {
NSMutableArray *array = @[].mutableCopy;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);//定義鎖的類別
__block pthread_mutex_t mutex;
pthread_mutex_init(&mutex, &attr);
pthread_mutexattr_destroy (&attr);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&mutex);
[array addObject:@"1"];
[NSThread sleepForTimeInterval:1];
NSLog(@"thread1");
pthread_mutex_unlock(&mutex);
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
pthread_mutex_lock(&mutex);
[array addObject:@"2"];
[NSThread sleepForTimeInterval:2];
NSLog(@"thread2");
pthread_mutex_unlock(&mutex);
});
}