iOS雨笙 多线程的原理和实现

       首先,我们先来了解一下什么是线程.

        说到线程,就要区分线程和进程.一个正在运行的程序叫做一个进程.多进程,顾名思义,就是多个程序正在运行.而线程,指的是一个程序或者一个进程中的运行"通道".每个进程中都有一个或者多个线程,如果只有一个,我们叫它主线程,主线程主要负责的是用户能看得见的东西,比如刷新界面,添加控件.除了一个主线程,其余的都是子线程.子线程和主线程是相互独立的.子线程主要负责用户看不到的任务,比如数据加载,任务下载.

       之所以会有主线程,子线程的区分,是因为有一些任务是不需要用户去一直等待的.比如图片的加载,在图片没有加载出来的情况下,我们是选择让用户去等待还是可以去执行其它的操作?显然,用户等待加载是不现实的,而主线程是顺序操作,所以在图片加载出来前是不会执行别的操作的,这个时候我们就需要子线程,就是单独创建一个和主线程不相关的线程,用这个子线程去加载图片,主线程则可以继续进行操作,等子线程加载完图片,再回到主线程来,提高了用户体验,但也会消耗一定的资源,所以不建议很多线程同时使用.

       下面介绍几个添加子线程的方法.

        (一)轻量级的线程 -- NSThread,可以开线程和终止线程.

// 创建一个线程,其实就是给他一个方法去执行
// 创建一个子线程专门打印
 NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(actionWhile) 
object:nil];
// 开启这个线程
 [thread start];
// 线程操作需注意:在主线程的时候,系统自动会添加了一个自动释放池,那么在开启子线程的时候,也要添加一个自动释放池
// 如果线程开的比较多,会造成代码比较乱,阅读性不高
// 一般方法中有自动释放池的基本上都是线程方法
       actionWhile方法中就是子线程要去实现的方法

// 
- (void)actionWhile
{
    // 添加一个自动释放池
    @autoreleasepool {
        // 要实现的方法

   }
}
        (二)基类中开启线程

        基类中也提供开启线程的类--NSOperation,这个类是个抽象类,没有具体功能,功能由NSBlockOperation,NSInvocationOperation实现,下面分别创建例子.

// 创建任务1
NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self 
selector:@selector(invocation1) object:nil];
// 创建任务2
NSBlockOperation *blockOP2 = [NSBlockOperation blockOperationWithBlock:^{
        // block块中就相当于添加的任务
        [self blockOP2];
}];
    
// 创建一个队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 把任务添加进队列当中
// 注意:添加任务前要设置依赖关系
// 依赖性(串行)
[invocation addDependency:blockOP2];
[queue addOperation:invocation];
[queue addOperation:blockOP2];
// 设置最大并发数,一起开始,谁先结束不知道
queue.maxConcurrentOperationCount = 2;
        下面再去实现相应的任务方法

// 实现任务一
- (void)invocation1
{
    // 子线程中添加一个自动释放池
    @autoreleasepool {
    // 当前线程的信息[NSThread currentThread]
    // [NSThread isMainThread]是否是主线程   
    // 打印出来的number是线程的个数,第几个线程
    NSLog(@"%@ 是不是主线程:%d",[NSThread currentThread],[NSThread isMainThread]);
    }
    
}

// 实现任务2
- (void)blockOP2
{
    // 添加释放池
    @autoreleasepool {
         NSLog(@"%@ 是不是主线程:%d",[NSThread currentThread],[NSThread isMainThread]);
    }
}
         (三)GCD(Grand Central Dispatch),是苹果公司开发的技术,以优化应用程序支持多核心处理器和其他的对称多处理系统地系统.GCD属于函数级的多线程,性能更高,功能也更强大.

          GCD分为串行队列和并行队列两种.

          串行队列又分为两种:1是主线程中的串行队列,会顺序执行,并且都会在主线程中执行.2是自定义的串行队列,会单独创建一个子线程去执行这些任务,并且这些任务在子线程中也是顺序执行的.

// 1.主线程中的串行队列(主串队列)
    // dispatch_queue GCD中表示一个队列
    // 创建一个主队列,实际上就是把主线程取出来了
//    dispatch_queue_t mainQueue = dispatch_get_main_queue();
//    // 添加任务
//    // 参数1:要添加任务的队列
//    // 参数2:要执行的任务
//    dispatch_async(mainQueue, ^{
//        NSLog(@"第一个任务,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
          currentThread].isMainThread);
//    });
//    // 任务2
//    dispatch_async(mainQueue, ^{
//        NSLog(@"第二个任务,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
          currentThread].isMainThread);
//    });
//    dispatch_async(mainQueue, ^{
//        NSLog(@"第三个任务,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
          currentThread].isMainThread);
//    });

    
    
    // 2.自定义的串行队列
    // 创建一个自定义的线程队列
    // 参数一:队列的标示符
    // 参数二:队列的执行类型(串|并)
    // DISPATCH_QUEUE_SERIAL串行
    dispatch_queue_t myQueue = dispatch_queue_create("com.ys.myQueue", DISPATCH_QUEUE_SERIAL);
    // 添加任务
    dispatch_async(myQueue, ^{
        NSLog(@"自定义第一个任务,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
        currentThread].isMainThread);
    });
    dispatch_async(myQueue, ^{
        NSLog(@"自定义第二个任务,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
        currentThread].isMainThread);
    });
    dispatch_async(myQueue, ^{
       NSLog(@"自定义第三个任务,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
       currentThread].isMainThread);
    });
    
    // 延迟回到主线程执行
    // delayInSeconds填延迟几秒
    // 延迟几秒后回到主线程执行任务
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), 
        dispatch_get_main_queue(), ^{
        NSLog(@"延迟5秒执行");
        NSLog(@"延迟5秒后,所在线程:%@, 是否是主线程:%d", [NSThread currentThread], [NSThread 
        currentThread].isMainThread);
    });
         并行队列也分为两种:1是全局队列,用 dispatch_get_global_queue去调用的,根据优先级访问队列.2是自定义并行队列,同时去执行,但谁先结束是不确定的.

         并行队列是在除了主线程外创建多个子线程(有几个任务创建几个子线程),然后并发执行.大家可以通过其打印的结果细细体会.

    // 1.全局队列
    // 参数1;队列的执行顺序,默认的
    // 参数2:预留参数,一般填0
//    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    dispatch_async(queue, ^{
//        for (int i = 0; i < 10; i++) {
//            NSLog(@"第一个任务,所在线程:%@, 是否是主线程:%d, %d", [NSThread currentThread], 
              [NSThread currentThread].isMainThread,i);
//        }
//    });
//    
//    dispatch_async(queue, ^{
//        for (int i = 10; i < 20; i++) {
//            NSLog(@"第二个任务,所在线程:%@, 是否是主线程:%d, %d", [NSThread currentThread], 
              [NSThread currentThread].isMainThread,i);
//        }
//    });
//
//    dispatch_async(queue, ^{
//        for (int i = 20; i < 30; i++) {
//            NSLog(@"第三个任务,所在线程:%@, 是否是主线程:%d, %d", [NSThread currentThread], 
              [NSThread currentThread].isMainThread, i);
//        }
//    });

//     2.自定义并行队列
    dispatch_queue_t myQueue = dispatch_queue_create("com.sy.king", DISPATCH_QUEUE_CONCURRENT);
    // 添加任务
    dispatch_async(myQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"第一个任务,所在线程:%@, 是否是主线程:%d, ----%d", [NSThread currentThread], 
            [NSThread currentThread].isMainThread,i);
        }
    });

    dispatch_async(myQueue, ^{
        for (int i = 10; i < 20; i++) {
            NSLog(@"第二个任务,所在线程:%@, 是否是主线程:%d, ----%d", 
            [NSThread currentThread], [NSThread currentThread].isMainThread,i);
        }
    });
    
    dispatch_async(myQueue, ^{
        for (int i = 20; i < 30; i++) {
            NSLog(@"第三个任务,所在线程:%@, 是否是主线程:%d, ----%d", [NSThread currentThread], 
            [NSThread currentThread].isMainThread, i);
        }
    });
       



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值