美文网首页
7.3 多线程-GCD

7.3 多线程-GCD

作者: 草根小强 | 来源:发表于2019-04-22 14:28 被阅读0次

    多线程-GCD

    多线程-GCD-串行并行

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //GCD -- 基于C语言的一套API/接口 用法非常简单,它是把block作为任务,添加到队列中进行操作
        //缺点:不能取消线程
        
        //GCD语法都是C语言函数
        //1.创建队列
        dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
        //queue 队列/线程池
        //dispatch 调度/执行
        //第一个参数:队列的名字 通常写nil
        //第二个参数:选择执行方式(串行 并行)
        //DISPATCH_QUEUE_SERIAL  串行
        //DISPATCH_QUEUE_CONCURRENT 并行
        //串行:按照添加到队列里的顺序依次执行线程
        //并行:不按照顺序执行线程 同时执行若干个线程
        
        [self createQueue1];
        
        [self createQueue2];
        
        //创建全局队列(并行队列)全局队列放的都是子线程,耗时的操作放到全局队列里
    //    queue = dispatch_get_global_queue(0, 0);
        //第一个参数:通常就写0  第二个参数:选择优先级通常使用默认优先级
        /*
         #define DISPATCH_QUEUE_PRIORITY_HIGH 2
         #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
         #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
         #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
         */
        
        //主队列 相当于拿到主线程
    //    queue = dispatch_get_main_queue();
        
        //同步执行 使用很少
        //下面这种写法会造成线程的相互等待/死循环
    //    dispatch_sync(dispatch_get_main_queue(), ^{
    //        NSLog(@"同步执行");
    //    });
        
        NSLog(@"主线程");
    }
    
    - (void)createQueue1{
        //创建串行的队列
        dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
        
        //将线程放到队列里执行
        //async 异步执行  把block作为任务/线程
        dispatch_async(queue, ^{
            
            NSLog(@"串行-%@-1",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            
            NSLog(@"串行-%@-2",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            
            NSLog(@"串行-%@-3",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            
            NSLog(@"串行-%@-4",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            
            NSLog(@"串行-%@-5",[NSThread currentThread]);
        });
        //当前队列里有5个任务 这个5个任务会依次执行
        
    }
    
    - (void)createQueue2{
        //创建并行队列
        dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            NSLog(@"并行-%@-1",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"并行-%@-2",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"并行-%@-3",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"并行-%@-4",[NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"并行-%@-5",[NSThread currentThread]);
        });
        //并行 5个线程同时执行
    }
    
    @end
    
    
    多线程-GCD.png

    GCD-线程的通讯、延时操作、定时器

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (nonatomic,strong) UIImageView *imageView;
    
    //使用GCD定时器 需要将它定义成全局变量
    @property (nonatomic,strong) dispatch_source_t timer;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.imageView = [[UIImageView alloc]initWithFrame:self.view.bounds];
        [self.view addSubview:self.imageView];
        
        [self createQueue1];
        
    //    [self createQueue2];
        
    //    [self createQueue3];
    }
    
    - (void)createQueue1{
        //创建全局队列
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        //异步请求数据
        dispatch_async(queue, ^{
           //创建子线程的目的:把耗时的操作放到子线程中
            //操作 -- 任务 -- 若干行代码(函数 block)
            NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/1.jpg"];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage *image = [UIImage imageWithData:data];
            //延时
            [NSThread sleepForTimeInterval:2.f];
            
            //让主线程显示数据
            //异步执行 让主队列执行
            dispatch_async(dispatch_get_main_queue(), ^{
               
                //显示数据
                self.imageView.image = image;
            });
        });
    }
    
    - (void)createQueue2{
        NSLog(@"将要延时");
        //延时几秒操作
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //DISPATCH_TIME_NOW 从现在开始
            //NSEC_PER_SEC 秒
            
            //延时几秒之后的操作
            NSLog(@"延时执行");
        });
        
        //NSObject的延时操作方法
    //    [self performSelector:@selector(afterRun) withObject:nil afterDelay:2.f];
    //    //取消延时操作
    //    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }
    - (void)afterRun{
        NSLog(@"也是延时操作");
    }
    
    - (void)createQueue3{
        //GCD定时器
        //1.创建定时器
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
        //2.设置定时器
        dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2.f * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
        //3. 定时器定时的操作
        dispatch_source_set_event_handler(self.timer, ^{
            //定时器每个几秒钟要做的事情
            NSLog(@"GCD定时器");
        });
        //4.执行定时器
        dispatch_resume(self.timer);
        
        
        //NSTimer定时器 相对于GCD定时器更加精确
    //    [NSTimer scheduledTimerWithTimeInterval:2.f
    //                                     target:self
    //                                   selector:@selector(timerRun) userInfo:nil
    //                                    repeats:YES];
    }
    
    - (void)timerRun{
        NSLog(@"NSTimer定时器");
    }
    @end
    

    GCD-线程组

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        
        [self createGroup1];
    }
    
    - (void)createGroup1{
        //创建线程组
        dispatch_group_t group = dispatch_group_create();
        //创建全局队列
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        
        //异步执行线程组
        dispatch_group_async(group, queue, ^{
           
            [NSThread sleepForTimeInterval:2.f];
            
            NSLog(@"线程1执行完毕");
        });
        
        dispatch_group_async(group, queue, ^{
           
            [NSThread sleepForTimeInterval:4.f];
            
            NSLog(@"线程2执行完毕");
        });
        
    //    dispatch_group_async(group, queue, ^{
    //       
    //        NSLog(@"线程3执行完毕");
    //    });
        
        //前两个线程结束后会通知这个线程  接到通知后在运行当前线程
    //    dispatch_group_notify(group, queue, ^{
    //       
    //        NSLog(@"线程3执行完毕");
    //    });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            
            NSLog(@"主线程执行");
        });
    }
    
    GCD-线程组1.png

    GCD-信号量、栏栅、重复

    - (void)crerateGroup2{
        
        dispatch_group_t group = dispatch_group_create();
        //异步操作
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            
            for (int i = 0; i < 5; i++) {
                //进入线程组
    //            dispatch_group_enter(group);
                
                [NSThread sleepForTimeInterval:1.f];
                NSLog(@"线程---%d",i);
                
                //离开线程组
    //            dispatch_group_leave(group);
            }
        });
        
        //目的:先执行完前面的线程 在执行后面的线程
        //阻塞线程
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        //DISPATCH_TIME_FOREVER 直到永远
        
        //异步操作
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
           
            NSLog(@"另一个线程执行了");
        });
    }
    
    GCD-线程组2.png
    #import "ViewController.h"
    
    @interface ViewController ()
    @property (strong, nonatomic) UIImageView *imageView1;
    @property (strong, nonatomic) UIImageView *imageView2;
    
    @property (strong, nonatomic) UIImageView *imageView3;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
    //    [self createQueue1];
        
    //    [self createQueue2];
        
    //    [self createQueue3];
        
        [self createQueue4];
    }
    
    - (void)createQueue1{
        //重复执行某个线程
        //第一个参数:要重复执行几次
        dispatch_apply(50, dispatch_get_global_queue(0, 0), ^(size_t num) {
            NSLog(@"线程执行了...");
        });
        
    }
    
    - (void)createQueue2{
        
        dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            sleep(1);
            NSLog(@"线程1...");
        });
        
        dispatch_async(queue, ^{
            sleep(1);
            NSLog(@"线程2...");
        });
        
        //barrier 屏障 前面的线程完之后 在执行当前线程和后面的线程
        dispatch_barrier_async(queue, ^{
           
            NSLog(@"线程3...");
        });
        
        dispatch_async(queue, ^{
    //        sleep(1);
            NSLog(@"线程4...");
        });
    }
    
    - (void)createQueue3{
        
        //信号量
        //创建信号量
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            //等待接收信号  接收信号要写在当前线程所有操作之前
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            NSLog(@"线程1执行了...");
        });
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            sleep(1);
            NSLog(@"线程2执行了...");
            
            //发送信号  在当前线程操作执行完毕之后 在发送信号
            dispatch_semaphore_signal(semaphore);
        });
    }
    
    - (void)createQueue4{
        self.imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 100)];
        self.imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 100, 300, 100)];
        self.imageView3 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 200, 300, 100)];
    
        self.imageView1.alpha = 0;
        self.imageView2.alpha = 0;
        self.imageView3.alpha = 0;
    
        [self.view addSubview:self.imageView1];
        [self.view addSubview:self.imageView2];
        [self.view addSubview:self.imageView3];
    
        //创建信号量
        dispatch_semaphore_t sem = dispatch_semaphore_create(0);
        dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            //子线程 下载数据
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://onepiece.local/SH/1.jpg"]];
            
            dispatch_async(dispatch_get_main_queue(), ^{
               //主线程 显示数据
                [UIView animateWithDuration:2.f animations:^{
                    
                    self.imageView1.image = [UIImage imageWithData:data];
                    self.imageView1.alpha = 1.0;
                } completion:^(BOOL finished) {
                    //显示完成后 发送信号
                    dispatch_semaphore_signal(sem);
                }];
                
            });
        });
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            //子线程 下载数据
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://onepiece.local/SH/2.jpg"]];
            dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
            dispatch_async(dispatch_get_main_queue(), ^{
                
                //主线程 显示数据
               [UIView animateWithDuration:2.f animations:^{
                   
                    self.imageView2.image = [UIImage imageWithData:data];
                   self.imageView2.alpha = 1.0;
               } completion:^(BOOL finished) {
                  dispatch_semaphore_signal(sem2);
               }];
            });
        });
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            //子线程 下载数据
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://onepiece.local/SH/3.jpg"]];
            dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);
            dispatch_async(dispatch_get_main_queue(), ^{
                //主线程 显示数据
                [UIView animateWithDuration:2.f animations:^{
                    
                    self.imageView3.image = [UIImage imageWithData:data];
                    self.imageView3.alpha = 1.0;
                } completion:^(BOOL finished) {
                    
                }];
            });
        });
    }
    @end
    

    GCD-信号量实例

    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (nonatomic,strong) UIImageView *imageView1;
    
    @property (nonatomic,strong) UIImageView *imageView2;
    
    @property (nonatomic,strong) UIImageView *imageView3;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        
        self.imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/3)];
        self.imageView1.alpha = 0;
        [self.view addSubview:self.imageView1];
        
        self.imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, self.view.bounds.size.height/3, self.view.bounds.size.width, self.view.bounds.size.height/3)];
        self.imageView2.alpha = 0;
        [self.view addSubview:self.imageView2];
        
        self.imageView3 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 2*self.view.bounds.size.height/3, self.view.bounds.size.width, self.view.bounds.size.height/3)];
        self.imageView3.alpha = 0;
        [self.view addSubview:self.imageView3];
        
        
        //http://onepiece.local/SH/1.jpg
        //http://onepiece.local/SH/2.jpg
        //http://onepiece.local/SH/3.jpg
        
        //创建信号量
        dispatch_semaphore_t sem1 = dispatch_semaphore_create(0);
        dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);
        
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
           //子线程 下载数据
            NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/1.jpg"];
            NSData *data = [NSData dataWithContentsOfURL:url];
            
            //主线程显示数据/刷新UI
            dispatch_async(dispatch_get_main_queue(), ^{
               
                [UIView animateWithDuration:2.f animations:^{
                    
                    self.imageView1.image = [UIImage imageWithData:data];
                    self.imageView1.alpha = 1.f;
                    
                } completion:^(BOOL finished) {
                    //第一张图片显示完之后 给第个线程发送信号 让第二张图片显示
                    dispatch_semaphore_signal(sem1);
                }];
            });
        });
        //第二个线程
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            //子线程 下载数据
            NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/2.jpg"];
            NSData *data = [NSData dataWithContentsOfURL:url];
            
            //等待信号量sem1 直到接收到sem1这个信号量 再继续向下执行
            dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER);
            
            //主线程显示数据/刷新UI
            dispatch_async(dispatch_get_main_queue(), ^{
                
                [UIView animateWithDuration:2.f animations:^{
                    
                    self.imageView2.image = [UIImage imageWithData:data];
                    self.imageView2.alpha = 1.f;
                    
                } completion:^(BOOL finished) {
                    //第二张图片显示完成 给线程3发送信号 让第三张图片显示
                    dispatch_semaphore_signal(sem2);
                }];
            });
        });
        //第三个线程
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            //子线程 下载数据
            NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/3.jpg"];
            NSData *data = [NSData dataWithContentsOfURL:url];
            
            //等待信号量sem2 然后再继续向下执行
            dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);
            
            //主线程显示数据/刷新UI
            dispatch_async(dispatch_get_main_queue(), ^{
                
                [UIView animateWithDuration:2.f animations:^{
                    
                    self.imageView3.image = [UIImage imageWithData:data];
                    self.imageView3.alpha = 1.f;
                    
                } completion:^(BOOL finished) {
                    
                }];
            });
        });
        
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:7.3 多线程-GCD

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