共享资源加锁的操作方法-10-多线程

  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 使用-浅析

 

posted on 2016-04-20 23:35  爱你久久iOS  阅读(301)  评论(0编辑  收藏  举报

导航