iOS开发系列-多线程

iOS创建多线程的4种方式

  • 1 pthread : C语言 只需了解,暂不介绍
  • 2 NSThread
  • 3 GCD
  • 4 NSOperation

特别注意:以下测试方法全部在主线程中调用

方式一:pthread创建方式

该方式暂不介绍

方式二:NSThread创建线程三种方法

  • 对象方法
  • 分类方法
  • 类方法

对象方法

代码示例:

   NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(nslogThread) object:nil];
    //注意启动一个线程并非就一定立即执行,而是处于就绪状态,当系统调度时才真正执行
    [thread start];
- (void) nslogThread {
    sleep(5);
    NSLog(@"%@",[NSThread currentThread]);
  NSLog(@"callBack");
}

分类方法

特别注意:
另外performSelectorOnMainThread方法是NSObject的分类方法,每个NSObject对象都有此方法,
它调用的selector方法是当前调用控件的方法,例如使用UIImageView调用的时候selector就是UIImageView的方法
Object:代表调用方法的参数,不过只能传递一个参数(如果有多个参数请使用对象进行封装)
waitUntilDone:是否线程任务完成才往下边执行
//如果YES,则,阻塞当前线程,直至新开辟线程执行完毕,才往下执行
//如果NO,不阻塞当前线程

    //在当前线程中执行(当前线程为主线程)
    NSLog(@"before");
    [self performSelectorOnMainThread:@selector(nslogThread) withObject:nil waitUntilDone:YES];
    NSLog(@"after");
    //创建新的线程
    //[self performSelectorInBackground:@selector(nslogThread) withObject:nil];
    //2016-05-26 13:04:28.595 NSThread三种方法[46373:1704985] {number = 2, name = (null)}

类方法


    //分类方法
    //selector:当前调用控件的方法,
    //target:由哪一个对象执行该方法
    //Object:代表调用方法的参数,不过只能传递一个参数(如果有多个参数请使用对象进行封装)
    [NSThread detachNewThreadSelector:@selector(nslogThread) toTarget:self withObject:nil];
    //2016-05-26 12:45:02.773 NSThread三种方法[45067:1693652] {number = 2, name = (null)}

方式三:GCD创建线程

首先我们要弄明白GCD中的核心概念
核心概念:

  • 任务
    1 同步任务: 在当前线程中的任务,不会开启新的线程
    2 异步任务:不在当前线程中的任务,会开启新的线程
  • 队列
    1 串行队列
    2 并发队列
    3 全局队列
    4 主队列

串行队列

串行队列-同步任务

-(void)serialQueue_syn{
   
   //1 任务
   void (^task1)(void)=^(){
       
       NSLog(@"task:%d,%@",1,[NSThread currentThread]);
   };
   void (^task2)(void)=^(){
       
       NSLog(@"task:%d,%@",2,[NSThread currentThread]);
   };
   void (^task3)(void)=^(){
       
       NSLog(@"task:%d,%@",3,[NSThread currentThread]);
   };
   
   //2 创建串行队列
   //参数1:该队列的名字
   //参数2:创建何种队列,如果DISPATCH_QUEUE_SERIAL则代表创建串行队列,其中#define DISPATCH_QUEUE_SERIAL NULL,即也可传入NULL
   dispatch_queue_t serialQueue=dispatch_queue_create("serialQueue_syn", DISPATCH_QUEUE_SERIAL);
   
   //3 向队列中添加同步任务
   dispatch_sync(serialQueue, task1);
   dispatch_sync(serialQueue, task2);
   dispatch_sync(serialQueue, task3);
   
   NSLog(@"serialQueue_over");
}

输出结果:
[1913:704162] task:1,{number = 1, name = main}
[1913:704162] task:2,{number = 1, name = main}
[1913:704162] task:3,{number = 1, name = main}
[1913:704162] serialQueue_over

串行队列-异步任务

-(void)serialQueue_asyn{
    
    void (^task1)(void)=^(){
        
        NSLog(@"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog(@"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog(@"task:%d,%@",3,[NSThread currentThread]);
    };
    
    //创建串行队列
    dispatch_queue_t serialQuere=dispatch_queue_create("serialQueue_asyn", NULL);
    
    //向队列中添加异步任务
    dispatch_async(serialQuere, task1);
    dispatch_async(serialQuere, task2);
    dispatch_async(serialQuere, task3);

    NSLog(@"serialQueue_asyn");
}

输出结果:
[1916:704616] serialQueue_asyn
[1916:704631] task:1,{number = 2, name = (null)}
[1916:704631] task:2,{number = 2, name = (null)}
[1916:704631] task:3,{number = 2, name = (null)}

** 串行队列总结:**
在串行队列中,同步任务则不创建新的线程,异步任务创建新的线程(只创建1条),对加入其中的任务,按照加入队列中的顺序执行,不改变任务的执行序列。

并发队列

并发队列-同步任务

-(void)concurrentQueue_syn{
    
    void (^task1)(void)=^(){
        
        NSLog( @"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog( @"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog( @"task:%d,%@",3,[NSThread currentThread]);
    };
    void (^task4)(void)=^(){
        
        NSLog( @"task:%d,%@",4,[NSThread currentThread]);
    };
    void (^task5)(void)=^(){
        
        NSLog( @"task:%d,%@",5,[NSThread currentThread]);
    };
    //2 创建并发队列
    //参数1:队列名字
    //参数2:创建队列类型:DISPATCH_QUEUE_CONCURRENT并发类型
    dispatch_queue_t concurrentQueue=dispatch_queue_create("concurrentQueue_syn", DISPATCH_QUEUE_CONCURRENT);
    
    //3 向队列中添加同步任务
    dispatch_sync(concurrentQueue, task1);
    dispatch_sync(concurrentQueue, task2);
    dispatch_sync(concurrentQueue, task3);
    dispatch_sync(concurrentQueue, task4);
    dispatch_sync(concurrentQueue, task5);
    NSLog(@"concurrent");
}

执行结果:
[1928:709535] task:1,{number = 1, name = main}
[1928:709535] task:2,{number = 1, name = main}
[1928:709535] task:3,{number = 1, name = main}
[1928:709535] task:4,{number = 1, name = main}
[1928:709535] task:5,{number = 1, name = main}
[1928:709535] concurrent

并发队列-异步任务

-(void) concurrentQueue_asyn{
    
    void (^task1)(void)=^(){
      
        NSLog( @"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog( @"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog( @"task:%d,%@",3,[NSThread currentThread]);
    };
    void (^task4)(void)=^(){
        
        NSLog( @"task:%d,%@",4,[NSThread currentThread]);
    };
    void (^task5)(void)=^(){
        
        NSLog( @"task:%d,%@",5,[NSThread currentThread]);
    };
    //创建并发队列
    //参数1:队列名字
    //参数2:创建队列类型:DISPATCH_QUEUE_CONCURRENT并发类型
    dispatch_queue_t concurrentQueue=dispatch_queue_create("concurrentQueue_asyn", DISPATCH_QUEUE_CONCURRENT);
    
    //向队列中添加异步任务
    dispatch_async(concurrentQueue, task1);
    dispatch_async(concurrentQueue, task2);
    dispatch_async(concurrentQueue, task3);
    dispatch_async(concurrentQueue, task4);
    dispatch_async(concurrentQueue, task5);
    
    NSLog(@"concurrent_asyn_over");
}

执行结果:
[1932:710530] concurrent_asyn_over
[1932:710569] task:4,{number = 5, name = (null)}
[1932:710568] task:3,{number = 4, name = (null)}
[1932:710559] task:2,{number = 3, name = (null)}
[1932:710560] task:1,{number = 2, name = (null)}
[1932:710570] task:5,{number = 6, name = (null)}

并发队列总结:
在并发队列中,同步任务不开辟线程,异步任务创建随机创建N条线程,并且任务执行顺序为无序状态

全局队列

全局队列-同步任务

-(void)globalQueue_async{
    
    void (^task1)(void)=^(){
        
        NSLog( @"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog( @"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog( @"task:%d,%@",3,[NSThread currentThread]);
    };
    void (^task4)(void)=^(){
        
        NSLog( @"task:%d,%@",4,[NSThread currentThread]);
    };
    void (^task5)(void)=^(){
        
        NSLog( @"task:%d,%@",5,[NSThread currentThread]);
    };
    
    
    //2 获得全局队列
    dispatch_queue_t globalQueue=dispatch_get_global_queue(0, 0);
    //3 向全局队列中添加异任务
    dispatch_async(globalQueue, task1);
    dispatch_async(globalQueue, task2);
    dispatch_async(globalQueue, task3);
    dispatch_async(globalQueue, task4);
    dispatch_async(globalQueue, task5);
    
    NSLog(@"globalQueue_async");
}

执行结果:
[1954:716253] task:1,{number = 1, name = main}
[1954:716253] task:2,{number = 1, name = main}
[1954:716253] task:3,{number = 1, name = main}
[1954:716253] task:4,{number = 1, name = main}
[1954:716253] task:5,{number = 1, name = main}
[1954:716253] globalQueue_sync

全局队列-异步任务

-(void)globalQueue_async{
    
    void (^task1)(void)=^(){
        
        NSLog( @"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog( @"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog( @"task:%d,%@",3,[NSThread currentThread]);
    };
    void (^task4)(void)=^(){
        
        NSLog( @"task:%d,%@",4,[NSThread currentThread]);
    };
    void (^task5)(void)=^(){
        
        NSLog( @"task:%d,%@",5,[NSThread currentThread]);
    };
    
    
    //2 获得全局队列
    dispatch_queue_t globalQueue=dispatch_get_global_queue(0, 0);
    //3 向全局队列中添加异任务
    dispatch_async(globalQueue, task1);
    dispatch_async(globalQueue, task2);
    dispatch_async(globalQueue, task3);
    dispatch_async(globalQueue, task4);
    dispatch_async(globalQueue, task5);
    
    NSLog(@"globalQueue_async");
}

执行结果:
[1958:716810] globalQueue_async
[1958:716924] task:3,{number = 4, name = (null)}
[1958:716921] task:2,{number = 3, name = (null)}
[1958:716922] task:1,{number = 2, name = (null)}
[1958:716926] task:4,{number = 5, name = (null)}
[1958:716928] task:5,{number = 6, name = (null)}

全局队列总结:
在全局队列中,同步任务不开辟线程,异步任务开辟N条随机线程,并且任务执行顺序为无序状态

主队列

主队列-同步任务

-(void)mainQueue_sync{
    
    //创建任务
    void (^task1)(void)=^(){
        
        NSLog( @"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog( @"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog( @"task:%d,%@",3,[NSThread currentThread]);
    };
    void (^task4)(void)=^(){
        
        NSLog( @"task:%d,%@",4,[NSThread currentThread]);
    };
    void (^task5)(void)=^(){
        
        NSLog( @"task:%d,%@",5,[NSThread currentThread]);
    };
    
    //2 获取系统主队列
    dispatch_queue_t mainQueue=dispatch_get_main_queue();
    
    //3 向主队列中添加同步任务
    dispatch_sync(mainQueue, task1);//在此处:一直在等带主线执行完毕,而主线程一直在等待该任务执行完毕
    dispatch_sync(mainQueue, task2);
    dispatch_sync(mainQueue, task3);
    dispatch_sync(mainQueue, task4);
    dispatch_sync(mainQueue, task5);
    
    NSLog(@"mainQueue_sync");
}

输出结果:
什么也没有输出,因为:向主队列中添加同步任务会出现死等状态。

主队列-异步任务

-(void)mainQueue_async{
    
    void (^task1)(void)=^(){
        
        NSLog( @"task:%d,%@",1,[NSThread currentThread]);
    };
    void (^task2)(void)=^(){
        
        NSLog( @"task:%d,%@",2,[NSThread currentThread]);
    };
    void (^task3)(void)=^(){
        
        NSLog( @"task:%d,%@",3,[NSThread currentThread]);
    };
    void (^task4)(void)=^(){
        
        NSLog( @"task:%d,%@",4,[NSThread currentThread]);
    };
    void (^task5)(void)=^(){
        
        NSLog( @"task:%d,%@",5,[NSThread currentThread]);
    };
    
    //2 获取系统主队列
    dispatch_queue_t mainQueue=dispatch_get_main_queue();
    
    //3 向主对列中添加异步任务
    dispatch_async(mainQueue, task1);
    dispatch_async(mainQueue, task2);
    dispatch_async(mainQueue, task3);
    dispatch_async(mainQueue, task4);
    dispatch_async(mainQueue, task5);
    
    NSLog(@"mainQueue_async");
}

输出结果:
mainQueue_async
task:1,{number = 1, name = main}
task:2,{number = 1, name = main}
task:3,{number = 1, name = main}
task:4,{number = 1, name = main}
task:5,{number = 1, name = main}

主队列总结:
在主队列中,同步任务会卡死主线程,异步任务不会创建线程,而是在主线程中执行。

方式四:NSOperation创建线程

核心概念:队列NSOperationQueue和任务NSOperation

队列NSOperationQueue分类:

  • 主 队 列:由系统提供,通过[NSOperationQueue new]方式获取
  • 并发队列:程序员创建[[NSOperationQueue alloc] init]方式获取

任务NSOperation分类:

  • NSInvationOperation类型任务
  • NSBlockOperation类型任务

主队列

操作主队列-NSInvationOperation类型任务

-(void)operationQueueAsynDemo1{
    //1 获取主队列
    NSOperationQueue *mainQueue=[NSOperationQueue mainQueue];
    //1 创建invocation任务
    NSInvocationOperation *invocationOper=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test:) object:@"mainQueue"];
    //3 向对列中添加任务
    [mainQueue addOperation:invocationOper];
}

-(void)test:(NSString *)info{
    NSLog( @"%@--%@",info,[NSThread currentThread]);
}

输出结果:
主队列[2015:729865] mainQueue--{number = 1, name = main}

主队列-NSBlockOperation类型任务

-(void)operationQueueAsynDemo2{
    
    //1 获取主队列
    NSOperationQueue *mainQueue=[NSOperationQueue mainQueue];
    //2 创建block任务
    NSBlockOperation *blockOperation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-->%@",[NSThread currentThread]);
        
    }];
    //3 向队列中添加block任务
    [mainQueue addOperation:blockOperation];
}

-(void)test:(NSString *)info{
    NSLog( @"%@--%@",info,[NSThread currentThread]);
}

输出结果:
主队列[2018:730534] -->{number = 1, name = main}

添加block任务简略方式:

-(void)operationQueueAsynDemo2{
    //1 获取主队列
    NSOperationQueue *mainQueue=[NSOperationQueue mainQueue];
    //2 创建block任务
    NSBlockOperation *blockOperation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"-->%@",[NSThread currentThread]);
        
    }];
    //3 向队列中添加block任务
    [mainQueue addOperation:blockOperation];
}

** NSOperationQueue主队列总结:**
NSOperationQueue主队列不创建线程,并且异步方式执行,不然阻塞主线程。

并发队列

操作并发队列-NSInvationOperation类型任务

//并发队列 Invocation任务
-(void)operationQueueAsynDemo1 {
    
    //1 创建队列:冲过alloc init方式创建的队列为并发异步队列
    NSOperationQueue *concurrentQueue=[[NSOperationQueue alloc] init];
    //2 创建任务
    NSInvocationOperation *invocationOperation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperationSyn:) object:@"OperationQueue_syn"];
    //3 向队列中添加任务
    [concurrentQueue addOperation:invocationOperation];
}

-(void)invocationOperationSyn:(NSString *)info{
        NSLog(@"%@--%@",info,[NSThread currentThread]);
}

   

输出结果:
[2023:732400] -->{number = 2, name = (null)}

并发队列-NSBlockOperation类型任务

//并发队列 block任务
-(void)operationQueueAsynDemo2{
    
    //1 创建并发对列
    NSOperationQueue *concurrentQueue=[[NSOperationQueue alloc] init];
    //2 创建block任务
    NSBlockOperation *blockOperation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog( @"%@-->",[NSThread currentThread]);
    }];
    //3 向队列中添加任务
    [concurrentQueue addOperation:blockOperation];
}

-(void)invocationOperationSyn:(NSString *)info{
        NSLog(@"%@--%@",info,[NSThread currentThread]);
}

输出结果:
[2026:733095] {number = 2, name = (null)}-->

添加block任务简略方式:

-(void ) operationQueueAsynDemo3{
    
    //1 创建并发队列
    NSOperationQueue *concurrent=[[NSOperationQueue alloc] init];
    //2 向队里中添加 blok
    [concurrent addOperationWithBlock:^{
        NSLog(@"%@",[NSThread currentThread]);
        
    }];
}

** NSOperationQueue并发队列总结:**
NSOperationQueue并发队列创建线程,并且异步方式执行

你可能感兴趣的:(iOS开发系列-多线程)