美文网首页
关于多线程

关于多线程

作者: 忘惘的小风扇 | 来源:发表于2016-07-07 18:11 被阅读18次

    一、NSThread

    1、判断当前是不是主线程:
    BOOL isMainThread =  [NSThread isMainThread];
    2、创建线程
    /*下面是创建线程的几种方法*/
    方法一:通过实例方法创建子线程,需要手动开启
    NSThread * thread = [[NSThread alloc]initWithTarget:self selected:@selecter(doSth) object:nil];
    thread.name = @"一条闪闪发光子线程";//可以给线程命名
    [thread start];//需要手动开启线程
    
    方法二:通过类方法创建线程,不需要手动开启线程,会直接执行@selecter()方法
    [NSThread detachNewThreadSelector:@selector(doSth) toTarget:self withObject:nil];
    
    方法三://隐式的创建一条新的线程
    [self performSelectorInBackground:@selector(doSth) withObject:nil];
    
    3.实现新线程所需方法
    -(void)doSth{
        NSURL *url = [NSURL URLWithString:@"需要下载的文件路径"];
        NSData *data = [[NSData alloc]initWithContentsOfURL:url];
       
        //线程间通讯(传值),不允许在子线程中刷新UI,实现异步下载
        [self performSelectorOnMainThread:@selector(updateUI:) withObject:data waitUntilDone:YES];
    }    
    4、刷新UI的方法
    -(void)updateUI:(NSData*)data{//将下载的文件加载到视图上
        self.imageView.image = [UIImage imageWithData:data];
    }
    
    
    1、当有多个线程同时访问或修改同一个资源时,会出现问题。此时,我们需要用线程锁来解决
    2、当添加线程锁的时候,是对资源的管理,而不是对线程的管理
    3、对资源添加线程锁,其实就是把这个资源变成原子性操作(atomic)
    
    线程锁的定义:NSLock *_lock;
    锁的创建:_lock = [[NSLock alloc]init];
    加锁:[_lock lock];
    解锁:[_lock unlock];
    

    二、NSOperation

    //NSOperation 底层是基于GCD来实现的
    //NSoperation 是一个抽象类,无法直接使用,它只是定义了一些方法,并没有实现,我们需要使用它的子类,在子类中去实现对应的方法。
    //系统定义的NSOperation的子类
    //1.NSInvocationOperation
    //2.NSBlockOperation
    
    //首先
    @interface ViewController ()
    @property (nonatomic,strong) NSOperationQueue *queue;
    @end
    //然后在 @implementation ViewController 中
    NSInvocationOperation *task1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(taskOne) object:nil];
    NSBlockOperation *task2 = [NSBlockOperation blockOperationWithBlock:^{
         [self taskTwo];
     }];
     NSInvocationOperation *task3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(taskThree) object:nil];
     //自定义队列
     NSOperationQueue * queue = [[NSOperationQueue alloc]init];
    //把任务交给队列来管理,那么任务是并发的,并且任务都是在子线程中来完成的,不需要去调用start方法,会自动的执行
    //同一时间的最大并发数,必须写在添加任务之前
    queue.maxConcurrentOperationCount = 2;
    
    //设置依赖关系,前者依赖于后者
    //后者先执行,执行完成后,再执行前者
    //一定要写在添加任务前
    [task2 addDependency:task1];
    [task3 addDependency:task2];
    
    //把任务交给队列来管理,任务执行的顺序是随机的
    [queue addOperation:task1];
    [queue addOperation:task2];
    [queue addOperation:task3];
    
    self.queue = queue;
    
    //控制自定义线程中任务的执行
    //暂停时,正在执行的任务是不受影响的,只有还没有执行的任务才会被暂停
    [self.queue setSuspended:YES]; //YES表示暂停,NO表示继续
    
    //取消所有任务,只能取消未执行的任务,取消任务后不能再继续
    [self.queue cancelAllOperations];
    

    三、GCD

    //自定义并行队列
    dispatch_queue_t queue = dispatch_queue_create("qf", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async (开启异步线程)
    
    //dispatch_barrier_async 使用用并行环境下
    //使用dispatch_barrier_async添加的任务会在之前的block全部运行完毕之后,才会继续执行。保证对非线程安全的对象进行正确的操作
    //运行完dispatch_barrier_async的block才会执行后面的任务
    //dispatch_barrier_async所在的线程跟前一个任务是同一条线程
    dispatch_barrier_async(queue, ^{
        NSLog(@"dispatch_barrier_async-%@",[NSThread currentThread]);
    });
    
    关于创建分组:
        //创建一个分组
        dispatch_group_t group = dispatch_group_create();
        
        //全局队列
        dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //第一个参数:任务所在的分组
        //第二个参数:任务所在的队列
        dispatch_group_async(group, globalQueue, ^{
            NSLog(@"分组任务1");
        });
        dispatch_group_async(group, globalQueue, ^{
            NSLog(@"分组任务2");
        });
        
        //当上面两个任务都完成以后,会执行这个方法,我们在这里处理我们的需求
        dispatch_group_notify(group, globalQueue, ^{
            
        });
    
    

    相关文章

      网友评论

          本文标题:关于多线程

          本文链接:https://www.haomeiwen.com/subject/asnkjttx.html