• 生产者消费者问题-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执行时间

    时光见证了成长,还很无知,我想一点点幼稚转为有知!
  • 相关阅读:
    Sentinel-1雷达数据可以免费下载
    影像下载
    遥感影像下载地址
    ERS卫星
    alos 数据下载
    RMSE、RMS、标准差
    Landsat8数据不同波段组合的用途
    资源下载
    短视频录制的一个例子,拥有美颜滤镜、人脸贴纸功能。
    an iOS demo to demonstrate how to decorate face like faceu
  • 原文地址:https://www.cnblogs.com/foreveriOS/p/5413994.html
Copyright © 2020-2023  润新知