美文网首页
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