iOS多线程之线程安全和GCD

在iOS中多线程一直是不可或缺的一部分,下面就说几种多线程的使用,下面介绍一种多线程使用的经典场景

首先我们介绍NSThread
创建线程

 _thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
    _thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
    _thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];

我们让线程去对数据进行操作
设置一个数值为20
出于线程安全的考虑,我们锁住当前线程并使其等待一些时间

 -(void)run{
    while (true) {
        //锁住当前线程对象,其他线程等待
        @synchronized(self) {
            if (_count > 0) {
                //使线程休眠一段时间(进行计算)
                [NSThread sleepForTimeInterval:0.00003];
                _count --;

                NSLog(@" ==== %@操作后的结果为%d",[NSThread currentThread].name,_count);
            }else{
                //退出线程
                NSLog(@"xiancheng ==== %@",[NSThread currentThread].name);
                 [NSThread exit];//退出线程,但是线程仍为开启状态
            }
        }
    }
}

出现的打印结果如下

2016-06-02 19:44:22.209 ThreadSafeDemo[768:36946]  ==== 第一个窗口操作后的结果为19
2016-06-02 19:44:22.210 ThreadSafeDemo[768:36947]  ==== 第二个窗口操作后的结果为18
2016-06-02 19:44:22.211 ThreadSafeDemo[768:36948]  ==== 第三个窗口操作后的结果为17
2016-06-02 19:44:22.212 ThreadSafeDemo[768:36946]  ==== 第一个窗口操作后的结果为16

下面我们用GCD实现图片加载
分别采用串行队列、并行队列,和组队列的加载方式

串行队列

   dispatch_queue_t queueT  = dispatch_queue_create("com.down", DISPATCH_QUEUE_SERIAL);

    __weak ViewController *weakSelf = self;//防止循环引用
    dispatch_async(queueT, ^{//执行异步线程下载图片
        UIImage *img = [weakSelf downLoadIMG:@"http://image.fvideo.cn/uploadfile/2012/03/15/20120315110710016.jpg"];
        dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
            _imgView2.image = img;
        });
    });

    __weak ViewController *weakSelf2 = self;//防止循环引用
    dispatch_async(queueT, ^{
        UIImage *img =  [weakSelf2 downLoadIMG:@"http://imagefiles.dfhon.com/imagefiles/2010/20101102/151049%20%281%29.jpg"];
        dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
            _imgView3.image = img;
        });
    });

会很明显的发现一个加载的先后顺序

并行队列

 //创建并行对象
    dispatch_queue_t queueT = dispatch_queue_create("com.down", DISPATCH_QUEUE_CONCURRENT);

    __weak ViewController *weakSelf = self;//防止循环引用
    dispatch_async(queueT, ^{//执行异步线程下载图片
        UIImage *img = [weakSelf downLoadIMG:@"http://image.fvideo.cn/uploadfile/2012/03/15/20120315110710016.jpg"];
        dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
            _imgView2.image = img;
        });
    });

    __weak ViewController *weakSelf2 = self;//防止循环引用
    dispatch_async(queueT, ^{
        UIImage *img =  [weakSelf2 downLoadIMG:@"http://imagefiles.dfhon.com/imagefiles/2010/20101102/151049%20%281%29.jpg"];
        dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
            _imgView3.image = img;
        });
    });

这样下载也会出现一个先后出现的问题,但是先后出现的顺序是随机的,那么怎么样才能同时加载呢

组队列

    //创建组
    dispatch_group_t group = dispatch_group_create();

    //组队列
    dispatch_queue_t groupT = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    __block UIImage *img1 = nil;
    __weak ViewController *weakSelf = self;//防止循环引用
    dispatch_group_async(group, groupT, ^{
        img1 = [weakSelf downLoadIMG:@"http://imagefiles.dfhon.com/imagefiles/2010/20101102/151049%20%281%29.jpg"];
    });

     __block UIImage *img2 = nil;
    __weak ViewController *weakSelf2 = self;//防止循环引用
    dispatch_group_async(group, groupT, ^{
         img2 = [weakSelf2 downLoadIMG:@"http://image.fvideo.cn/uploadfile/2012/03/15/20120315110710016.jpg"];
    });

    //在下载完成之后通知主队列加载图片
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        _imgView2.image = img1;
        _imgView3.image = img2;
    });
-(UIImage *)downLoadIMG:(NSString *)url{//图片的下载方法
    NSURL *urlAA = [NSURL URLWithString:url];
    NSData *data = [NSData dataWithContentsOfURL:urlAA];
    NSLog(@"data == %@",data);
    UIImage *img = [UIImage imageWithData:data];

    return img;
}

你可能感兴趣的:(线程篇)