美文网首页
ios 多线程你需要了解的

ios 多线程你需要了解的

作者: 赵哥窟 | 来源:发表于2018-08-16 15:35 被阅读11次

    了解多线程之前首先要了解一下几个概念

    进程

    进程是指在系统中正在进行的一个应用程序;每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。

    线程

    一个进程要想执行任务,必须得有线程(每一个进程至少要有一条线程),是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位;

    多线程

    进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务。多线程技术可以提高程序的执行效率。

    多线程原理

    单核CPU同一时间内能处理1条线程,多线程并发执行,其实是CPU快速地在多条线程之间调度。如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象。

    多线程的优缺点

    优点:能适当提高程序的执行效率;能适当提高资源利用率(CPU、内存利用率)。
    缺点:开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能;线程越多,CPU在调度线程上的开销就越大;程序设计更加复杂,例如线程之间的通信、多线程的数据共享。

    同步和异步的区别

    同步:只能在当前线程中执行任务,不具备开启新线程的能力
    异步:可以在新的线程中执行任务,具备开启新线程的能力

    并发和串行

    并发:多个任务并发(同时)执行
    串行:一个任务执行完毕后,再执行下一个任务

    线程间怎么通信

    NSThread

    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
    
    - (void)updateUI {
        // UI更新代码
        self.alert.text = @"Thanks!";
    }
    

    NSOperationQueue

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // UI更新代码
        self.alert.text = @"Thanks!";
        }];
    

    GCD

    dispatch_async(dispatch_get_main_queue(), ^{
       // UI更新代码
       self.alert.text = @"Thanks!";
    });
    
    多线程在ios中的运用
    1499394732413995.png
    NSThread的使用

    NSThread创建线程
    /** 方法一,需要start */

    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething1:) object:@"NSThread1"];
    // 线程加入线程池等待CPU调度,时间很快,几乎是立刻执行
    [thread1 start];
    
    - (void)doSomething1:(NSObject *)object {
        // 传递过来的参数
        NSLog(@"%@",object);
        NSLog(@"doSomething1:%@",[NSThread currentThread]);
    }
    

    /** 方法二,创建好之后自动启动 */

    [NSThread detachNewThreadSelector:@selector(doSomething2:) toTarget:self withObject:@"NSThread2"];
    
    - (void)doSomething2:(NSObject *)object {
        NSLog(@"%@",object);
        NSLog(@"doSomething2:%@",[NSThread currentThread]);
    }
    

    /** 方法三,隐式创建,直接启动 */

    [self performSelectorInBackground:@selector(doSomething3:) withObject:@"NSThread3"];
    
    - (void)doSomething3:(NSObject *)object {
        NSLog(@"%@",object);
        NSLog(@"doSomething3:%@",[NSThread currentThread]);
    }
    

    返回当前线程

    // 当前线程
    [NSThread currentThread];
    NSLog(@"%@",[NSThread currentThread]);
    

    阻塞休眠

    //休眠多久
    [NSThread sleepForTimeInterval:2];
    //休眠到指定时间
    [NSThread sleepUntilDate:[NSDate date]];
    

    其他一些方法

    //退出线程
    [NSThread exit];
    //判断当前线程是否为主线程
    [NSThread isMainThread];
    //判断当前线程是否是多线程
    [NSThread isMultiThreaded];
    //主线程的对象
    NSThread *mainThread = [NSThread mainThread];
    
    GCD的理解与使用

    GCD中有2个核心概念
    (1)任务:执行什么操作
    (2)队列:用来存放任务

    队列

    不管是什么队列,一定是FIFO队列,即先进先出。
    所以,请大家记住了:不管是串行队列(SerialQueue)还是并发队列(ConcurrencyQueue),都是FIFO队列。也就意味着,任务一定是一个一个地,按照先进先出的顺序来执行。

    串行队列:
    在创建队列时,传参数DISPATCH_QUEUE_SERIAL表示创建串行队列。任务会一个一个地执行,只有前一个任务执行完成,才会继续执行下一个任务。串行执行并不是同步执行的意思,一定要注意区分。

    并发队列:
    在创建队列时,传参数DISPATCH_QUEUE_CONCURRENT表示创建并发队列。并发队列会尽可能多地创建线程去执行任务。并发队列中的任务会按入队的顺序执行任务,但是哪个任务先完成是不确定的。

    串行队列

    dispatch_queue_t serialQueue = dispatch_queue_create("serial_queue", 
    DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue, ^{
      NSLog(@"s1");
     });
    dispatch_async(serialQueue, ^{
      sleep(2);
      NSLog(@"s2");
    });
    dispatch_async(serialQueue, ^{
    sleep(1);
    NSLog(@"s3");
    });
    
    打印 s1,s2,s3
    

    并发队列

    dispatch_queue_t concurrencyQueue = dispatch_queue_create("com.huangyibiao.concurrency-queue",
                                                                  DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(concurrencyQueue, ^{
            NSLog(@"s1");
        });
        dispatch_async(concurrencyQueue, ^{
            sleep(2);
            NSLog(@"s2");
        });
        dispatch_async(concurrencyQueue, ^{
            sleep(1);
            NSLog(@"s3");
        });
    
    打印 s1,s3,s2
    

    同步异步线程

    // 全局并发队列的获取方法
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 同步执行任务创建方法
    dispatch_sync(queue, ^{
        // 这里放同步执行任务代码
    });
    // 异步执行任务创建方法
    dispatch_async(queue, ^{
        // 这里放异步执行任务代码
    });
    

    相关文章

      网友评论

          本文标题:ios 多线程你需要了解的

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