1 在多线程的编程环境中,锁的使用必不可少! 2 于是,今天来总结一下为共享资源加锁的操作方法。 3 4 一、使用synchronized方式 5 6 //线程1 7 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 8 @synchronized(_myLockObj){ 9 [obj1 method1]; 10 sleep(30); 11 } 12 @synchronized(obj1){ 13 14 15 16 } 17 }); 18 19 //线程2 20 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 21 sleep(1); 22 @synchronized(_myLockObj){ 23 [obj1 method2]; 24 } 25 }); 26 27 } 28 29 这样,就会起到锁的作用,线程2会等待线程1执行完成@synchronized(obj){}块后,在执行。从而起到锁的作用。 30 31 2.使用NSLock方式 32 33 先贴一个例子: 34 35 1. TestObj.h 36 37 @interface TestObj : NSObject 38 - (void)method1; 39 - (void)method2; 40 @end 41 42 2. TestObj.m 43 44 #import "TestObj.h" 45 46 @implementation TestObj 47 48 - (void)method1{ 49 NSLog(@"%@",NSStringFromSelector(_cmd)); 50 NSLog(@"Current thread = %@", [NSThread currentThread]); 51 NSLog(@"Main thread = %@", [NSThread mainThread]); 52 } 53 54 - (void)method2{ 55 NSLog(@"%@",NSStringFromSelector(_cmd)); 56 NSLog(@"Current thread = %@", [NSThread currentThread]); 57 NSLog(@"Main thread = %@", [NSThread mainThread]); 58 59 } 60 61 @end 62 63 3.在需要锁的视图控制器中,申明锁对象。 64 65 TestObj *obj = [[TestObj alloc] init]; 66 NSLock *lock = [[NSLock alloc] init]; 67 68 4.多线程状态下,锁操作 69 70 71 //线程1 72 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 73 [lock lock]; 74 [obj method1]; 75 sleep(30); 76 [lock unlock]; 77 }); 78 79 //线程2 80 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 81 sleep(5);//以保证让线程2的代码后执行 82 [lock lock]; 83 [obj method2]; 84 [lock unlock]; 85 }); 86 87 5.总结 88 89 使用时,基本方法就是: 90 [lock lock]; 91 [obj yourMethod]; 92 [lock unlock]; 93 94 我们称[obj yourMethod]为“关键部分”。 95 NSLock的执行原理: 96 某个线程A调用lock方法。这样,NSLock将被上锁。可以执行“关键部分”,完成后,调用unlock方法。 97 如果,在线程A 调用unlock方法之前,另一个线程B调用了同一锁对象的lock方法。那么,线程B只有等待。直到线程A调用了unlock。 98 99 最后,还是看看API中对NSLock的一些说明 100 101 102 @protocol NSLocking 103 104 105 lock 方法 106 - (void)lock 107 获得锁 108 109 unlock 方法 110 - (void)unlock 111 释放锁 112 113 @interface NSLock 114 115 lockBeforeDate: 方法 116 - (BOOL)lockBeforeDate:(NSDate *)limit 117 在指定的时间以前得到锁。YES:在指定时间之前获得了锁;NO:在指定时间之前没有获得锁。 118 该线程将被阻塞,直到获得了锁,或者指定时间过期。 119 120 121 tryLock 方法 122 - (BOOL)tryLock 123 视图得到一个锁。YES:成功得到锁;NO:没有得到锁。 124 125 126 setName: 方法 127 - (void)setName:(NSString *)newName 128 为锁指定一个Name 129 130 name 方法 131 - (NSString *)name 132 返回锁指定的Name 133 134 135 三、使用GCD中dispatch_semaphore_t和dispatch_semaphore_wait 136 137 TestObj *obj = [[TestObj alloc] init]; 138 dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); 139 140 //线程1 141 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 142 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 143 [obj method1]; 144 sleep(10); 145 dispatch_semaphore_signal(semaphore); 146 }); 147 148 //线程2 149 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 150 sleep(1); 151 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 152 [obj method2]; 153 dispatch_semaphore_signal(semaphore); 154 }); 155 156 关于GCD中dispatch_semaphore_create和dispatch_semaphore_wait的使用。请参见我的另一篇博客: 157 158 GCD(Grand Central Dispatch)和Block 使用-浅析