实现分线程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/48010147

实现分线程

预备概念:

1.进程:一个正在执行的程序

2.线程:由一堆不分叉的CPU指令组成的集合(一个进程中至少包含一个线程)

3.上下文切换:假设一个CPU同时负责两个线程,当线程1时间片结束以后会将线程1的相关信息保存到寄存器中。接下来将时间片分配给线程2,线程2时间片到了以后又将线程2信息保存起来。接下来唤醒线程1的寄存器,将其信息取出,接着上一次执行的命令继续执行,来回切换,直到所有的CPU命令全部完成。

4.多线程的优势和缺点:

一.缺点:

(1)每个线程都会开辟一个空间,如果大量使用多线程会占用大量内存影响性能。

(2)资源竞争。   上锁    

(3) 死锁。

二. 优点:

提高用户体验

我们现在的主要目的是实现分线程,目前了解到的有三种方式

1.利用NSObject实现分线程:

开辟一个分线程的代码:

[selfperformSelectorInBackground:@selector(getData)withObject:nil];

分线程中的代码:

- (void)getData {

NSString *path =@"http://c.hiphotos.baidu.com/image/h%3D200/sign=4652d7cac8bf6c81e8372be88c3fb1d7/ d50735fae6cd7b89448109210b2442a7d8330ea6.jpg";

NSURL *url = [NSURLURLWithString:path];

NSData *data = [NSDatadataWithContentsOfURL:url];

UIImage *image = [UIImageimageWithData:data];

    [selfperformSelectorOnMainThread:@selector(refreshUI:)withObject:image waitUntilDone:NO];

}

此分线程中的代码是获取网络上的一幅图片,这就要设计到刷新UI的问题,刷新UI只能在主线程中,当分线程下载完数据后一定要立刻返回到主线程中,否则就会有延迟。虽然不返回也能实现刷新的效果,这是因为主线程会定时访问分线程,看其是否完成了任务。

主线程刷新UI的代码:

- (void)refreshUI:(id)obj {

self.myImageView.image = obj;

}

2.利用NSThread实现分线程

开辟分线程的代码:

//   创建一个线程

NSThread *thread = [[NSThreadalloc] initWithTarget:selfselector:@selector(getData)object:nil];

//    需要手动启动线程

    [thread start];

利用NSThread这个类来创建,和其他类创建对象是一样的,至于其分线程中的代码是和NSObject中的代码一样的就不太粘贴了。

3.GCD异步下载数据:

GCD:Grand Central Dispatch

利用GCD可以创建队列,然后将任务添加到队列中,这样就产生了一个线程来完成队列中的任务,线程中所有任务结束结束后同样要返回到主线程。

代码:

dispatch_queue_t queue = dispatch_queue_create("com.qianfeng",NULL);

NSLog(@"--%@",[NSThreadcurrentThread]);

dispatch_async(queue, ^{

NSLog(@"++%@",[NSThreadcurrentThread]);

NSString *path =@"http://c.hiphotos.baidu.com/image/h%3D200/sign=4652d7cac8bf6c81e8372be88c3fb1d7/          

d50735fae6cd7b89448109210b2442a7d8330ea6.jpg";    

NSURL *url = [NSURLURLWithString:path];

NSData *data = [NSDatadataWithContentsOfURL:url];

UIImage *image = [UIImageimageWithData:data];

__weak typeof(self) weakSelf =self;

//        回到主线程

dispatch_async(dispatch_get_main_queue(), ^{

//            回到主线程刷新UI,如果不回到主线程刷新UI,刷新会有延迟

            weakSelf.myImageView.image = image;

NSLog(@"回到主线程:%@",[NSThreadcurrentThread]);

        });

    });

sleep(2);

NSLog(@"====%@",[NSThreadcurrentThread]);

创建队列中的第二个参数为空说明创建的是一个串行队列(什么是串行队列? 待会说)。代码中的几个nslog语句可以显示程序的执行顺序,并不是执行完分线程,才再去执行主线程的(我们添加分线程是为了提高速度,缩短程序运行时间,提高用户体验)。

说说串行队列:

队列可以分为串行队列和并行队列,联想一下串行电路和并行电路。当队列是串行队列的时候,队列中添加的任务是按顺序执行的,哪怕添加再多的任务也只是一个线程而已。(串行队列中的任务执行顺序只与添加的顺序有关)  与串行队列相对应的是并行队列,并行队列中任务的执行顺序是不确定的,一个并行队列中可能有多个线程,因为只要往队列中添加一个任务就会产生一个线程。

并行队列:

并行队列的创建和串行队列的创建相似,只是第二个参数有所变化。

代码:

dispatch_queue_t queue =dispatch_queue_create("com.1000phone",DISPATCH_QUEUE_CONCURRENT);

切记任务完成后返回主线程。

在并行队列中我们可以利用group来监听并行队列中的全部线程什么时候结束(并行队列中线程的执行顺序是不确定,不好判断什么时候结束,不像并行队列那样,可以在所有任务后再添加一个任务来显示串行队列中的所有任务结束)。

代码:

//    1.创建一个并行队列

dispatch_queue_t queue =dispatch_queue_create("com.1000phone",DISPATCH_QUEUE_CONCURRENT);

//    2.创建一个group

dispatch_group_t group =dispatch_group_create();

//    3.将任务添加到队列里面

//    (1)任务一

dispatch_group_async(group, queue, ^{

sleep(3);

dispatch_async(dispatch_get_main_queue(), ^{

NSLog(@"任务一处理完成");

        });

    });

//    (2)任务二

dispatch_group_async(group, queue, ^{

sleep(1);

dispatch_async(dispatch_get_main_queue(), ^{

NSLog(@"任务二处理完成");

        });

    });

    });

//    4.通过group监听什么时候所有任务全处理完成

dispatch_group_notify(group,dispatch_get_main_queue(), ^{

NSLog(@"队列中所有任务已经处理完成");

    });

以上这么多代码也全是唬人的,实际比前面的队列创建实现分线程也就是多个一个group的创建,和通过group监听。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS开发中利用dispatch group实现并发多任务

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

    用户1451823
  • iOS开发中在指定的某些线程执行完之后去执行其他线程

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

    用户1451823
  • NSOperation的简单使用代码

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

    用户1451823
  • 【原创】Java并发编程系列32 | 阻塞队列(下)

    阻塞队列在并发编程非常常用,被广泛使用在“生产者-消费者”问题中。本文是阻塞队列下篇。

    java进阶架构师
  • 三歪花了几天总结了多线程知识

    在上两周总结了一篇「工作中常用到的Java集合类」,反响还不错。这周来写写Java另一个重要的知识点:「多线程」

    Java3y
  • Python线程和进程(下)

    queue是python的标准库,俗称队列.可以直接import引用,在python2.x中,模块名为Queue。python3是小写的queue即可

    润森
  • java线程池,工作窃取算法

    在上一篇《java线程池,阿里为什么不允许使用Executors?》中我们谈及了线程池,同时又发现一个现象,当最大线程数还没有满的时候耗时的任务全部堆积给了单个...

    落跑架构师M
  • 使用Python进行线程编程

    对于Python来说,并不缺少并发选项,其标准库包括了对线程、进程和异步I/O的支持。在许多情况下,通过创建诸如异步、线程和子进程之类的高层模块,Python...

    py3study
  • java线程池,工作窃取算法

    在上一篇《java线程池,阿里为什么不允许使用Executors?》中我们谈及了线程池,同时又发现一个现象,当最大线程数还没有满的时候耗时的任务全部堆积给了单个...

    落跑架构师M
  • Java面试题汇总---基础版(附答案)

    基于我个人对面试的认知和招聘经验,在此我总结一下Java开发者的基础知识掌握要求,及应聘者面试的需要准备的内容。

    攻城狮的那点事

扫码关注云+社区

领取腾讯云代金券