多线程

多线程

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);
        }
    });

}

 

posted @ 2015-04-16 19:23  W_LR  阅读(225)  评论(0编辑  收藏  举报