多线程

多线程

1.多线程

  pthread

  NSThread

  NSOPeration

  GCD--支持多核

2.NSThread

  (1)

    //NSThread多线程的使用

    //1.创建线程

#pragma mark - 1.创建线程

-(void)createThread{

    

    //*******顺序执行(串行执行)*/

//    [self taskA];

//   [self taskB];

    

    //*******并行执行(多个任务同时执行)********/

    //创建新的线程

    //方式一(创建之后不会立即执行)

    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(taskA) object:nil];

    [thread1 start];

    //方式二(创建之后立即执行)

    //需设置Object:thread1  --> 线程之间的控制与通信

    [NSThread detachNewThreadSelector:@selector(taskB:) toTarget:self withObject:thread1];

}
-(void)taskA{



    for(int i=0;i<20;i++){

    

        NSLog(@"A = %d",i);

        

//        每次检测是否应该取消

        if([NSThread currentThread].isCancelled){   //取出当前线程--> 是否取消(若是,exit线程)

        

            [NSThread exit];  //退出线程

        }



        [NSThread sleepForTimeInterval:0.25];

    }

}

-(void)taskB:(NSThread *)thread{

    

    for(int i=0;i<20;i++){

        

        NSLog(@"B = %d",i);

        if(i==10){

        

            [thread cancel];   //线程B,发送cancel消息

          //  NSLog(@"tadkB: %@ , thread = %@",[NSThread currentThread],thread);

        }

        [NSThread sleepForTimeInterval:0.25];

    }

}

  (2)为何使用多线程,解决什么问题

#pragma mark - 2.为何使用多线程,解决什么问题

-(void)whyUseThread{



    //本质:  多线程主要解决 执行耗时任务时出现的UI界面阻塞的问题

    //       或同时执行多个任务(如 迅雷)

    //使用场景: 大麦网 -- 下载数据(耗时5s),图片(耗时10s)

    //         迅雷加载视频文件

    

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];

    [btn setTitle:@"耗时任务" forState:UIControlStateNormal];

    btn.frame = CGRectMake(100, 100, 100, 30);

    [btn addTarget:self action:@selector(startTask:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:btn];

    

}

-(void)startTask:(id)sender{



    //http://10.3.8.8/download/真机调试.tar.gz

    NSString *urlString = @"http://10.3.8.8/download/真机调试.tar.gz";

    //只能放在子线程,会卡

    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]];

    NSLog(@"size = %u",data.length);

    

}

  (3)使用通知监听线程结束

    //3.使用通知监听线程结束

//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dealTheardExit) name:NSThreadWillExitNotification object:nil];
#pragma mark - 3.使用通知监听线程结束

-(void)dealTheardExit{



    NSLog(@"线程结束");

}

  (4)线程的控制和通信

//4.线程的控制和通信

    //  A --> i=10时,B stop

  (5)

 //5.线程的同步锁

    //多个线程访问同一块内存 --> 解决(NSLock 锁)

    _lock = [[NSLock alloc] init];

//    [NSThread detachNewThreadSelector:@selector(add) toTarget:self withObject:nil];

//    [NSThread detachNewThreadSelector:@selector(sub) toTarget:self withObject:nil];
#pragma mark - 5.线程的同步锁

-(void)add{



    for(int i=0;i<1000;i++){

        

        [_lock lock];   //加锁

        _num++;

        NSLog(@"add = %d",_num);

        [_lock unlock];  //解锁

    }

}

-(void)sub{

    

    for(int i=0;i<1000;i++){

        

        [_lock lock];

        _num--;

        NSLog(@"sub = %d",_num);

        [_lock unlock];

    }

}

  (6)

    //6.子线程如何更新UI(very import)

    //限制 : UI线程--> 主线程

    //       其他创建的线程--子线程

    //      注:不要在子线程直接操作UI--> 让主线程操作

    //下载进度更新

//    [NSThread detachNewThreadSelector:@selector(downloadNetWorkData) toTarget:self withObject:nil];

    // [self downloadNetWorkData];

    _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(10, 200, 300, 20)];

    [self.view addSubview:_progressView];
#pragma mark - 6.

-(void)downloadNetWorkData{

    

    for(int i=0;i<100;i++){

    

        [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];   //在主线程里改变UI

        [NSThread sleepForTimeInterval:0.1];  //

    }

}

3.NSOperation

//************************NSOperation使用************************/

    //***1.NSOperation  --> NSThread类似,实现多线程的机制。。更抽象,加入了block,更简单易用

    

    //***2.NSOperation抽象类-->NSInvocationOperation,NSBlockOperation

    //NSInvocationOperation

    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];

//    [invocationOperation start];   //创建之后需要执行-->start ,默认同步执行

    

    //NSBlockOperation

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

        

        for(int i=0;i<20;i++){

            

            NSLog(@"B = %d",i);

        }

    }];

//    [blockOperation start];   //同上,默认同步执行

    

    //NSOperationQueue --> 操作队列,任务列表(注:异步平行执行)

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [queue addOperation:invocationOperation];  //添加队列

    [queue addOperation:blockOperation];

    

4.GCD

    //*****GCD的使用  --> Grand Central Dispatch  *******/

    //  好处: 1.支持多核; 2.C和block,易于使用 ; 3.较晚出现,功能强大,使用多

    

    //1.GCD 创建异步任务

//   [self createAsyncTask];

    

    //2.模拟网络下载

//    [self simulateNetWorkDownload];

    

    //3.只执行一次

    [self runOnce];

    

    //4.延迟执行

    [self delayRun];

    

    //5.同时执行多个任务,等待所有任务执行完成进行处理

    //eg: 迅雷所有任务完成自动关机

    [self groupRun];
#pragma mark - 5.同时执行多个任务,等待所有任务执行完成进行处理

-(void)groupRun{



    //group

    dispatch_group_t group = dispatch_group_create();   //添加到group

    //添加任务 7s

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        for(int i=0;i<100;i++){

        

            NSLog(@"A = %d",i);

            [NSThread sleepForTimeInterval:0.07];

        }

    });

    //  5s

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        for(int i=0;i<100;i++){

            

            NSLog(@"B = %d",i);

            [NSThread sleepForTimeInterval:0.05];

        }

    });

    //  10s

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        for(int i=0;i<100;i++){

            

            NSLog(@"C = %d",i);

            [NSThread sleepForTimeInterval:0.1];

        }

    });



    //

    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"自动关机");

    });

    

}



#pragma mark - 4.延迟执行

-(void)delayRun{



    //延迟5s 执行

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        NSLog(@"he he he");

    });

}



#pragma mark - 3.只执行一次

-(void)runOnce{



    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        NSLog(@"只执行一次的代码");

    });

    

}



#pragma mark - 2.模拟网络下载

-(void)simulateNetWorkDownload{



    UIProgressView *progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(10, 100, 300, 20)];

    [self.view addSubview:progressView];

    

    //GCD开启最简单的异步任务下载   主线程

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(queue, ^{

        //在子线程中执行

        for(int i=0;i<100;i++){

           //返回主线程执行

           dispatch_async(dispatch_get_main_queue() , ^{

               

               progressView.progress += 0.01;

               NSLog(@"progress = %f",progressView.progress);

           });

            

            [NSThread sleepForTimeInterval:0.1];

        }

        

        //最后显示对话框(子线程--> 需要切回main)

        dispatch_async(dispatch_get_main_queue(), ^{

            UIAlertView *alert = [[UIAlertView alloc] init];

            alert.message = @"下载完成";

            [alert addButtonWithTitle:@"取消"];

            [alert show];

        });

        

    });



}



#pragma mark - 1.GCD 创建异步任务

-(void)createAsyncTask{



    //参数1:  dispatch_queue_t queue  --> 有3种queue

    //              mian_queue 主队列(主线程), glabel_queue 全局队列(工作线程),自定义queue

    //参数2:  ^(void)block

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //执行异步任务

    dispatch_async(queue, ^{

       

        for(int i=0;i<20;i++){

        

            NSLog(@"A = %d",i);

        }

    });

    

    dispatch_async(queue, ^{

        

        for(int i=0;i<20;i++){

            

            NSLog(@"B = %d",i);

        }

    });



}

 

你可能感兴趣的:(多线程)