美文网首页
GCD之同步异步与串行并行队列详解

GCD之同步异步与串行并行队列详解

作者: Ariest | 来源:发表于2016-06-13 23:10 被阅读0次

同步只能在当前线程中执行任务,不具备开启新线程的能力。异步可以在新线程中执行任务,具备开启新线程的能力。
多线程:一个进程可以开启多条线程,每条线程可以执行不同的任务。实质上在同一时间,CPU只能处理一条线程,CPU快速在多线程间调度,产生并发执行假象。

多线程实例应用

-(void)test06
{
    #异步主队列: 异步不会阻塞主线程 主队列任务必须放在主线程执行
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"%@--A",[NSThread currentThread]);
    });
    
    #第一步: 主线程执行 输出B
    NSLog(@"%@--B",[NSThread currentThread]);

    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    #同步全局并发队列: 同步会阻塞主线程 第二步: 输出C 
    dispatch_sync(queue, ^{
        NSLog(@"%@--C",[NSThread currentThread]);
    });
    
    #异步全局并发队列: 开启新线程执行任务 未阻塞主线程 
    dispatch_async(queue, ^{    
        NSLog(@"%@--D",[NSThread currentThread]);
    });
    
    #异步主队列: 异步不会阻塞主线程 主队列任务必须放在主线程执行
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"%@--E",[NSThread currentThread]);
    });
    
    #此方法主线程执行  相当于异步主队列
    [self performSelector:@selector(testMethod) withObject:nil afterDelay:0];
    
    #第三步: 主队列执行 输出F
    NSLog(@"%@--F",[NSThread currentThread];

    /*
        主队列任务顺序: G->E->A
        输出结果为:
        B C F D A E G
    */
    
}

-(void)testMethod{
    
    NSLog(@"%@--G",[NSThread currentThread]);
}

#打印结果
 {number = 1, name = main}--B
 {number = 1, name = main}--C
 {number = 1, name = main}--F
 {number = 3, name = (null)}--D
 {number = 1, name = main}--A
 {number = 1, name = main}--E
 {number = 1, name = main}--G
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self test01];
    [self test02];
    [self test03];
    [self test04];
    [self test05];
}
-(void)test05{
    NSOperationQueue *queue=[[NSOperationQueue alloc] init];
    NSBlockOperation *operationA=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@--下载第A张图片",[NSThread currentThread]);
    }];
    NSBlockOperation *operationB=[NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"%@--下载第B张图片",[NSThread currentThread]);
    }];
    
    NSBlockOperation *operationC=[NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"%@--下载第C张图片",[NSThread currentThread]);
    }];
    
#    [queue addOperation:operationA];
#    [queue addOperation:operationB];
#    [queue addOperation:operationC];
   
    #设置依赖 按需求A B C 顺序执行
    [operationB addDependency:operationA];
    [operationC addDependency:operationB];
    
    #添加任务到队列
    [queue addOperation:operationA];
    [queue addOperation:operationB];
    [queue addOperation:operationC];
}

-(void)test04{
    
    NSOperationQueue *queue=[[NSOperationQueue alloc] init];
    
    #设置最大并发数
#    queue.maxConcurrentOperationCount=1;
    
    NSBlockOperation *operation1=[NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"%@--下载第一张图片",[NSThread currentThread]);
    }];
    
    NSBlockOperation *operation2=[NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"%@--下载第二张图片",[NSThread currentThread]);
    }];
    
    NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"%@--下载第三张图片",[NSThread currentThread]);
    }];
    
    #InvocationOperation
    NSInvocationOperation *operation4=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadOperation) object:nil];
    
    #添加操作到队列
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    [queue addOperation:operation4];
    
    [queue addOperationWithBlock:^{
        
        NSLog(@"%@--下载第四张图片",[NSThread currentThread]);
    }];
    
    [queue addOperationWithBlock:^{
        
        NSLog(@"%@--下载第五张图片",[NSThread currentThread]);
    }];
    
#    [queue cancelAllOperations];

}

-(void)downloadOperation{
    
    NSLog(@"downloadOperation--%@",[NSThread currentThread]);
}

-(void)test03{
    
    dispatch_group_t group=dispatch_group_create();
    
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    #下载第一张图片
    static UIImage *image1=nil;
#    __block UIImage *image1=nil;
    dispatch_group_async(group, queue, ^{
        
        NSURL *url1=[NSURL URLWithString:@"http:#pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"];
        NSData *data1=[NSData dataWithContentsOfURL:url1];
        image1=[UIImage imageWithData:data1];
        
        NSLog(@"image1--%@",[NSThread currentThread]);
    });
    
    #下载第二张图片
    static UIImage *image2=nil;
    #    __block UIImage *image2=nil;
    dispatch_group_async(group, queue, ^{
       
        NSURL *url2=[NSURL URLWithString:@"https:#www.baidu.com/img/bd_logo1.png"];
        NSData *data2=[NSData dataWithContentsOfURL:url2];
        image2=[UIImage imageWithData:data2];
        
        NSLog(@"image2--%@",[NSThread currentThread]);
    });

    
    dispatch_group_notify(group, queue, ^{
       
        NSLog(@"notify--%@",[NSThread currentThread]);
        
        #开启上下文
        UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
        
        #绘制第一张图片
        CGFloat image1W=image1.size.width;
        CGFloat image1H=image1.size.height;
        [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
        
        #绘制第二张图片
        CGFloat image2W=image2.size.width;
        CGFloat image2H=image2.size.height;
        [image2 drawInRect:CGRectMake(image1W-image2W, image1H-image2H, image2W, image2H)];
        
        #获取绘制好的图片
        UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
        
        #关闭上下文
        UIGraphicsEndImageContext();
        
        
        #回主线程刷新界面
        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"async--%@",[NSThread currentThread]);
             self.imageView.image=image;
        });

    });
    
}

-(void)test02{
    
    #第一张图片
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSURL *url1=[NSURL URLWithString:@"http:#pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"];
        NSData *data1=[NSData dataWithContentsOfURL:url1];
        self.image1=[UIImage imageWithData:data1];
        
        [self mergerImage];
        
    });
    
    
    #第二张图片
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        NSURL *url2=[NSURL URLWithString:@"https:#www.baidu.com/img/bd_logo1.png"];
        NSData *data2=[NSData dataWithContentsOfURL:url2];
        self.image2=[UIImage imageWithData:data2];
        
        [self mergerImage];
    });
    
}

#合并图片
-(void)mergerImage{
    
    if (self.image1 == nil || self.image2 == nil) {
        
        return;
    }else{
        
        UIGraphicsBeginImageContextWithOptions(self.image1.size, NO, 0.0);
        
        #绘制第一张图
        CGFloat image1W=self.image1.size.width;
        CGFloat image1H=self.image1.size.height;
        [self.image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
        
        #绘制第二张图
        CGFloat image2W=self.image2.size.width;
        CGFloat image2H=self.image2.size.height;
        [self.image2 drawInRect:CGRectMake(image1W-image2W, image1H-image2H, image2W, image2H)];
        
        #获取绘制后的图片
        UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
        
        UIGraphicsEndImageContext();
        
        #UI界面显示
        dispatch_async(dispatch_get_main_queue(), ^{
           
            self.imageView.image=image;
        });
        
    }
}


-(void)test01{
    
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        
        NSLog(@"%@--global_queue",[NSThread currentThread]);
        
        #下载第一张图片
        NSURL *url1=[NSURL URLWithString:@"http:#pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"];
        NSData *data1=[NSData dataWithContentsOfURL:url1];
        UIImage *image1=[UIImage imageWithData:data1];
        
        #下载第二张图片
        NSURL *url2=[NSURL URLWithString:@"https:#www.baidu.com/img/bd_logo1.png"];
        NSData *data2=[NSData dataWithContentsOfURL:url2];
        UIImage *image2=[UIImage imageWithData:data2];
        
        #合并图片
        
        UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0);
        
        #绘制第一张图片
        CGFloat image1W=image1.size.width;
        CGFloat image1H=image1.size.height;
        [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
        
        #绘制第二张图片
        CGFloat image2W=image2.size.width*0.5;
        CGFloat image2H=image2.size.height*0.5;
        [image2 drawInRect:CGRectMake(image1W-image2W, image1H-image2H, image2W, image2H)];
        
        #获取绘制好的合成图片
        UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
        
        UIGraphicsEndImageContext();
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
             NSLog(@"%@--main_queue",[NSThread currentThread]);
            
            self.imageView.image=image;
            
        });
        
    });

}

相关文章

  • IOS多线程总结

    目录 简述 NSThread GCD操作与队列异步操作并行队列同步操作并行队列同步操作串行队列异步操作串行队列队列...

  • 关于多线程GCD 串行/并行、同步/异步

    一、GCD串行/并行队列创建 串行队列: 并行队列: 二、GCD串行/并行队列同步/异步执行 执行内容1: 执行结...

  • GCD基础总结一

    上代码~ 同步串行队列 同步并行队列 异步串行队列 异步并行队列 主队列同步 会卡住 主队列异步

  • 多线程

    1、同步、异步、串行、并行、全局队列、主队列2、Thread、NSOperation、GCD3、锁

  • GCD

    1、同步串行队列 2、同步并行队列 3、异步串行队列 4、异步并行队列 5、死锁 主线程中创建同步串行队列 主线程...

  • GCD中的串行,并行,同步,异步详解

    gcd中的串行,并行,同步,异步详解 1、gcd中同步与异步的区别: gcd中的线程是由一个线程池来管理的,这个池...

  • iOS多线程操作GCD以及NSOperation简介

    GCD是一套C写的多线程模型,根据队列类型和是否同步可以分为并行同步,并行异步,串行同步,串行异步。具体使用可以查...

  • GCD 相关函数

    串行同步 串行异步 并行同步 并行异步 主队列同步 会死锁 主队列异步 异步处理耗时,回主线程刷新UI 栅栏函数 ...

  • GCD 细细的读

    目录 前言 为什么选择GCD? 串行队列、并行队列、同步、异步 线程死锁解析 DispatchQueue的使用 D...

  • 不可不说的多线程

    关键字:多线程原理,队列(串行并行),任务(同步异步),NSThread,GCD,NSOperation,@syn...

网友评论

      本文标题:GCD之同步异步与串行并行队列详解

      本文链接:https://www.haomeiwen.com/subject/ooaydttx.html