目的
- 使用NSOperationQueue達成執行緒實作
工具
- NSOperation
- 執行緒
- NSOperationQueue
- 執行緒池,將NSOperation放入交由系統執行
- NSCondition
- 類似JAVA中的synchronized機制,使用"lock" & "unlock"防止多執行緒同時存取相同的變數
﹣實現Producer & Consumer
Store.h
// Store用來管理Producer及Consumer一同存取的容器 // 故需要考慮到同步的問題,不可發生同時存取相同容器的問題 @interface Store : NSObject { NSMutableArray* mProducts; NSCondition* mLocker; } - (id) initStore; - (void) add:(NSNumber*) product; - (NSNumber*) get; @end
#import "Store.h" @implementation Store - (id) initStore { self = [super init]; if (self){ mProducts = [[NSMutableArray alloc] init]; mLocker = [[NSCondition alloc] init]; } return self; } - (void) add:(NSNumber*) product { // 同步add product階段 [mLocker lock]; while ([mProducts count] >= 2) { [mLocker wait]; } [mProducts addObject:product]; [mLocker signal]; // wake up one thread [mLocker unlock]; } - (NSNumber*) get { // 同步get product階段 [mLocker lock]; while ([mProducts count] <= 0) { [mLocker wait]; NSNumber* product = [mProducts objectAtIndex:0]; [mProducts removeObjectAtIndex:0]; [mLocker signal]; // wake up one thread [mLocker unlock]; return product; } @end
Producer.h
// 將數字放入容器中 #import "Store.h" @interface Producer : NSOperation { Store* mStore; } - (id) initProducer:(Store*) store; - (void) main; @endProducer.m
#import "Producer.h" @implementation Producer - (id) initProducer:(Store*) store { self = [super init]; if (self)Consumer.h{ mStore = store; } return self; } - (void) main { for (int iProduct = 1; iProduct <= 10; iProduct++) { // 隨機睡眠 0~4秒 [NSThread sleepForTimeInterval:(arc4random() % 5)]; [mStore add:[NSNumber numberWithInt:iProduct]]; NSLog(@"Produce %d", iProduct); } } @end
// 將收字從容器中拿出 #import "Store.h" @interface Consumer : NSOperation { Store* mSotre; } - (id) initConsumer:(Store*) store; - (void) main; @end
Consumer.m
#import "Consumer.h" @implementation Consumer - (id) initConsumer:(Store*) store { self = [super init]; if (self) { mSotre = store; } return self; } - (void) main { for (int iLoop = 0; iLoop <= 10; iLoop++) { [NSThread sleepForTimeInterval:(arc4random() % 5)]; NSLog(@"Consume %d", [[mSotre get] intValue]); } } @end
ViewController.h
#import "Producer.h" #import "Consumer.h" #import "Store.h" @interface ViewController : UIViewController { NSOperationQueue* mQueue; Producer* mProducer; Consumer* mConsumer; Store* mStore; } @end
ViewController.m
- (void)viewDidLoad { [super viewDidLoad]; mQueue = [[NSOperationQueue alloc] init]; mStore = [[Store alloc] initStore]; // 將Store放入Producer & Consumer裡 mProducer = [[Producer alloc] initProducer:mStore]; mConsumer = [[Consumer alloc] initConsumer:mStore]; // 將Producer & Consumer放入Operation queue中, // 開始執行Producer & Consumer [mQueue addOperation:mProducer]; [mQueue addOperation:mConsumer]; }
Note
- 其中"[mLocker signal];" 可代換成"[mLocker broadcast];",差別在於前者"signal"喚醒一個等待此thread的thread;而後者喚醒所有在等待此thread的thread
沒有留言:
張貼留言