1 // 2 // ViewController.m 3 // 06-生产者消费者问题 4 // 5 // Created by mac on 16/4/20. 6 // Copyright © 2016年 mac. All rights reserved. 7 // 8 9 /*生产者消费者处理线程同步问题 10 思路: 11 1).生产者要取得锁,然后生产(去库房中放其生产的商品),如果库房满了,则wait,这时释放锁。直到有线程唤醒它再去生产;如果没有满,则生产商品后发送signal(消息)可以唤醒等待的消费者。 12 2).消费者要取得锁,然后消费 (去库房拿取产品),如果没有商品,则wait,这时释放锁,直到有线程呼唤它去消费;如果有商品,则消费后通知正在wait的生产者 13 */ 14 #define kMaxProductCount 10 15 #import "ViewController.h" 16 17 @interface ViewController () 18 19 @end 20 21 @implementation ViewController { 22 23 //互斥锁和条件锁的结合 24 NSCondition *_condition; 25 26 //产品(库房) 27 NSMutableArray *_productArray; 28 } 29 30 - (void)viewDidLoad { 31 [super viewDidLoad]; 32 33 [self addThread]; 34 } 35 36 /** 37 * 添加(多)线程 38 */ 39 - (void)addThread { 40 41 _condition = [[NSCondition alloc] init]; 42 _productArray = [NSMutableArray array]; 43 44 [NSThread detachNewThreadSelector:@selector(producterAction) toTarget:self withObject:nil]; 45 [NSThread detachNewThreadSelector:@selector(producterAction) toTarget:self withObject:nil]; 46 [NSThread detachNewThreadSelector:@selector(producterAction) toTarget:self withObject:nil]; 47 [NSThread detachNewThreadSelector:@selector(consumerAction) toTarget:self withObject:nil]; 48 49 } 50 /** 51 * 生产者producter 52 */ 53 - (void)producterAction { 54 55 while (TRUE) { 56 //加锁,防止线程更改 57 [_condition lock]; 58 59 //判断库房是否已经满,满了,生产者得等待 60 while (kMaxProductCount == _productArray.count) { 61 NSLog(@"生产者等待"); 62 [_condition wait]; 63 } 64 65 //0.2 - 2s 模拟生产者生产商品过程:(arc4random() % 10 + 1) / 5.0 66 [NSThread sleepForTimeInterval:(arc4random() % 10 + 1) / 5.0]; 67 [_productArray addObject:[[NSObject alloc] init]]; 68 69 NSLog(@"total = %li", _productArray.count); 70 71 //唤醒在此condition上等待的单个消费者对象 72 [_condition signal]; 73 74 //广播,一对多:呼唤多个消费者 75 [_condition broadcast]; 76 77 [_condition unlock]; 78 } 79 } 80 81 /** 82 * 消费者consumer 83 */ 84 - (void)consumerAction { 85 86 while (TRUE) { 87 //加锁,防止线程更改 88 [_condition lock]; 89 90 //判断库房是否已经空,没了,消费者得等待 91 while (kMaxProductCount == 0) { 92 NSLog(@"空空空"); 93 [_condition wait]; 94 } 95 96 //0.2 - 2s 模拟生产者生产商品过程:(arc4random() % 10 + 1) / 5.0 97 [NSThread sleepForTimeInterval:(arc4random() % 10 + 1) / 5.0]; 98 [_productArray removeLastObject]; 99 100 NSLog(@"total = %li", _productArray.count); 101 102 //唤醒在此condition上等待的单个消费者对象 103 // [_condition signal]; 104 105 //唤醒在此condition上等待的所有消费者对象 106 [_condition unlock]; 107 } 108 } 109 110 111 @end
wait和sleep区别:
1. 来自不同的类-->sleep(NSThread的类方法)wait(NSCondition的类方法)
2.sleep用于线程控制(等待),wait用于线程通信(发送通知);(一个等待,一个发通知)
3.sleep方法不会释放锁,一直占用资源;wait释放了锁,进入线程池等待,让出系统资源。其它线程可以使用同步控制块或者方法,别的线程执行signal / broadcast才能够重新获得CPU执行时间