多线程

来源:互联网 发布:本机端口号查询 编辑:程序博客网 时间:2024/05/16 18:37

线程和进程的概述:
要说线程,这不得不先提到进程。通常操作系统可以同时执行多个任务,而每一个任务就是一个进程,而一个进程又能同时执行多个任务,每一个任务就是一个线程。多线程的开发可以最大限度的发挥多核处理器的优势。
进程可以理解为一个应用程序,他拥有自己独立的资源和私有的地址空间。在创建一个进程的时候,系统自动创建一个线程,这个线程被称为主线程。但当用户播放音频、下载资源、处理图像时,如果这些耗时的操作都在主线程执行的话,此时,主线程就会被阻塞,无法响应用户的操作,并发生“卡”的现象,这样会大大较低用户的体验度。而使用多线程就可以很好的解决此类问题。
进程中的线程之间它们可以共享内存、文件句柄,这让线程之间很容易实现相互之间的通信,从而极大的提高了程序的运行效率。所以可以将耗时的任务放在非主线程中执行(但更新UI界面需要在主线程中)。但线程的使用关键是要注意线程的执行顺序,处理好资源的争夺问题。iOS常用的多线程开发有三种方式:
1. NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程),使用简单,但需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒,线程同步对数据会对系统性能有一定的消耗。
2. NSOpreation 面向对象的线程技术,不需要关心线程的管理和数据的同步,可以控制并发线程的数量,和优先级。
3. GCD 是基于C语言的,线程的创建和回收有队列负责,也是苹果推荐使用的线程技术。
三种线程的技术实现
NSThread

  - (void)viewDidLoad {    [super viewDidLoad];    //多线程网络加载图片    //创建一个新的线程    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadImage) object:nil];    //开启线程    [thread start];}- (void)loadImage{    NSURL *url = [NSURL URLWithString:@"资源地址"];    //获取图片的二进制    NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];    UIImage *image = [UIImage imageWithData:imageData];    if (imageData != nil)    {        //在主线程中更行图片        [self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:YES];    }}- (void)updateImage:(UIImage *)image{    //将图片添加到界面上}

NSOperation

//实例化一个操作队列    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    //设置操作队列的做大线程数    queue.maxConcurrentOperationCount = 3;    //实例化操作    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i <= 5; i++) {            NSLog(@"--------%@",[NSThread currentThread]);        }    }];    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i <= 5; i++) {            NSLog(@"=========%@",[NSThread currentThread]);        }    }];    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i <= 5; i++) {            NSLog(@"+++++++++++%@",[NSThread currentThread]);        }    }];    //控制操作执行的优先级(必须先设置队列的附属关系,再操作队列中添加队列)    [operation1 addDependency:operation2];    //将操作添加到操作队列中    [queue addOperation:operation1];    [queue addOperation:operation2];    [queue addOperation:operation3];

GCD
GCD的两个核心概念:
队列:负责管理我们提交的任务,始终以先进先出的原则管理任务。队列可分为串行队列,并发队列和主队列,串行队列一次只执行一个任务,前一个任务执行完后一个任务才会开始执行;并发队列则可以同时执行多个任务,即多个任务并发执行。队列底层会维护一个线程池来处理我们提交的任务,串行队列只维护一个线程池,而并发队列会维护多个线程池。
任务:任务就是需要提交给队列的执行代码。任务可分为同步任务和异步任务。同步任务不会开辟新的线程的,异步任务会开辟新线程。如果在串行队列中执行异步任务,会新建线程,按顺序执行任务。如果在并行队列中执行异步任务,会新建线程,但无法确定任务的执行顺序。注意:主队列中添加同步任务永远不会被执行。

- (void)viewDidLoad{    [super viewDidLoad];    //在串行队列中执行异步任务    //创建一个串行对列  按任务添加顺序执行 并新建一个线程    dispatch_queue_t serialQueue = dispatch_queue_create("aa", DISPATCH_QUEUE_SERIAL);    dispatch_async(serialQueue, ^{        for (int i = 0; i < 10; i++) {            NSLog(@"我先执行%@",[NSThread currentThread]);        }    });    dispatch_async(serialQueue, ^{        for (int i = 0; i < 10; i++) {            NSLog(@"我后执行%@",[NSThread currentThread]);        }    });    //在并行队列中执行异步任务,会新建线程,但无法控制任务的执行顺序    //创建一个并发队列    //dispatch_queue_t concurrentQueue = dispatch_queue_create("bb", DISPATCH_QUEUE_CONCURRENT);    //使用系统默认的全局并发队列    dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    dispatch_async(defaultQueue, ^{        for (int i = 0; i < 10; i++) {            NSLog(@"异步执行%@",[NSThread currentThread]);        }    });    dispatch_async(defaultQueue, ^{        for (int i = 0; i < 10; i++) {            NSLog(@"异步执行%@",[NSThread currentThread]);        }    });    //在主队列中执行同步任务 (主队列中只能执行异步任务)    dispatch_sync(dispatch_get_main_queue(), ^{        NSLog(@"在主队列中更行UI控件");    });}
1 0
原创粉丝点击