• 多线程GCD dispatch_once_t/dispatch_barrier_<a>sync/dispatch_group_t


    dispatch_once

    dispatch_once block中的代码在程序启动到程序退回只会执行一次,如:不管for循环多少,只会一次打印

     

    for (int i = 0; i<10; i++) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
           NSLog(@"----once--");
        });
    }
    2017-09-02 14:53:13.085 GCD测试[11539:156889] ----once--

    利用dispatch_once实现单粒模式

    单粒模式(不管以任何方式创建对象,内存中永远只会有且仅有一份该对象的地址)

    实现单粒,需要步骤: 1.提供一个类方法,用以返回该对象 2.实现类方法(使用dispatch_once限制只运行一次) 3.重写 + allocWithZone:(struct _NSZone *)zone(通过alloc时会最终会调用 + allocWithZone:(struct _NSZone *)zone,所以直接实现+ allocWithZone就好,使用dispatch_once限制只运行一次)  4.实现 - (id)copyWithZone:(NSZone *)zone

    #ifndef Singleten_h
    #define Singleten_h
    
    #pragma mark - 实例定义
    #define SingletenInterface(name) 
    + (instancetype)shared##name;
    
    
    #pragma mark - 定义单例代码块
    #define SingletenImpl(name) 
    static id _instace; 
    
    + (id)allocWithZone:(struct _NSZone *)zone 
    { 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    _instace = [super allocWithZone:zone]; 
    }); 
    return _instace; 
    } 
    
    - (id)copyWithZone:(NSZone *)zone 
    { 
    return _instace; 
    } 
    
    + (instancetype)shared##name 
    { 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    _instace = [[self alloc] init]; 
    }); 
    return _instace; 
    } 
    
    
    
    #endif /* Singleten_h */
    

     此方式不能使用继承方式,要不然所有子类所有实例都是同一个

    线程栏杆barrier

    可以让栏杆前的任务先执行完,再执行栏杆后的任务,此处不要使用全局队列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),经测试如果使用global,barrier栏杆效果没有.

    dispatch_barrier_<a>sync:
        作用:在它前面的任务执行结束后它才执行,在它后面的任务等它执行完成后才会执行
        注意点:使用barrier时不要使用全局队列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 如果是dispatch_barrier_<a>sync不能使用全局队列,经测试是不起作用的
        
        dispatch_queue_t queue = dispatch_queue_create("HJiang", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            NSLog(@"1 %@",[NSThread currentThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"2 %@",[NSThread currentThread]);
        });
        
        dispatch_barrier_async(queue, ^{
            NSLog(@"---------barrier %@",[NSThread currentThread]);
        });
    
        dispatch_async(queue, ^{
            NSLog(@"3 %@",[NSThread currentThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"4 %@",[NSThread currentThread]);
        });
        2017-09-01 17:56:40.893 GCD测试[9872:286531] 1 <NSThread: 0x608000070800>{number = 3, name = (null)}
        2017-09-01 17:56:40.893 GCD测试[9872:286528] 2 <NSThread: 0x60000006f280>{number = 4, name = (null)}
        2017-09-01 17:56:40.893 GCD测试[9872:286494] ---------barrier <NSThread: 0x608000063280>{number = 1, name = main}
        2017-09-01 17:56:40.894 GCD测试[9872:286528] 3 <NSThread: 0x60000006f280>{number = 4, name = (null)}
        2017-09-01 17:56:40.894 GCD测试[9872:286531] 4 <NSThread: 0x608000070800>{number = 3, name = (null)}
    

    线程组

    dispatch_group_create:创建线程组

    dispatch_group_async:线程组异步任务

    dispatch_group_notify:线程组任务所有完成后,通知执行方法

    dispatch_group_wait:线程组等待,会阻塞当前线程,比较少用,特别是当前线程是主线程时,dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 5);

    //    dispatch_group_create()
    //    dispatch_group_async(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    //    dispatch_group_notify(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    //    dispatch_group_wait(<#dispatch_group_t  _Nonnull group#>, <#dispatch_time_t timeout#>)
    //    dispatch_group_enter(<#dispatch_group_t  _Nonnull group#>)
    //    dispatch_group_leave(<#dispatch_group_t  _Nonnull group#>)
        
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t queue = dispatch_queue_create("HJiang", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_async(group, queue, ^{
            for (int i = 0; i<5; i++) {
                NSLog(@"%zd --%@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_group_async(group, queue, ^{
            for (int i = 0; i<5; i++) {
                NSLog(@"%zd --%@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_group_wait(group, 10);
        
        dispatch_group_notify(group, queue, ^{
            for (int i = 0; i<5; i++) {
                NSLog(@"dispatch_group_notify %@ 组里的所有任务都执行完成后,执行notify",[NSThread currentThread]);
            }
        });
        
        NSLog(@"group end...");
        
        2017-09-02 14:42:43.269 GCD测试[11392:150458] 0 --<NSThread: 0x60800026a440>{number = 4, name = (null)}
        2017-09-02 14:42:43.269 GCD测试[11392:150459] 0 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)}
        2017-09-02 14:42:43.269 GCD测试[11392:150424] group end...
        2017-09-02 14:42:43.269 GCD测试[11392:150458] 1 --<NSThread: 0x60800026a440>{number = 4, name = (null)}
        2017-09-02 14:42:43.269 GCD测试[11392:150459] 1 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)}
        2017-09-02 14:42:43.270 GCD测试[11392:150458] 2 --<NSThread: 0x60800026a440>{number = 4, name = (null)}
        2017-09-02 14:42:43.270 GCD测试[11392:150459] 2 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)}
        2017-09-02 14:42:43.270 GCD测试[11392:150458] 3 --<NSThread: 0x60800026a440>{number = 4, name = (null)}
        2017-09-02 14:42:43.270 GCD测试[11392:150459] 3 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)}
        2017-09-02 14:42:43.270 GCD测试[11392:150458] 4 --<NSThread: 0x60800026a440>{number = 4, name = (null)}
        2017-09-02 14:42:43.271 GCD测试[11392:150459] 4 --<NSThread: 0x60800026a2c0>{number = 3, name = (null)}
        2017-09-02 14:42:43.271 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify
        2017-09-02 14:42:43.271 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify
        2017-09-02 14:42:43.272 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify
        2017-09-02 14:42:43.272 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify
        2017-09-02 14:42:43.272 GCD测试[11392:150459] dispatch_group_notify <NSThread: 0x60800026a2c0>{number = 3, name = (null)} 组里的所有任务都执行完成后,执行notify
    

     

  • 相关阅读:
    ThinkingInJava对this关键字的介绍
    MYSQL(三)
    MySQL(二)
    mysql语句实战
    js事件委托
    Python中应该使用%还是format来格式化字符串?
    js高级知识---词法分析和AO 链
    lsof/netstat命令的一个重要作用: 根据进程查端口, 根据端口查进程
    gg
    io多路复用
  • 原文地址:https://www.cnblogs.com/HJiang/p/7464460.html
Copyright © 2020-2023  润新知