生产者消费者问题-05-多线程

  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执行时间

时光见证了成长,还很无知,我想一点点幼稚转为有知!
原文地址:https://www.cnblogs.com/foreveriOS/p/5413994.html