多线程NSThread、NSOperation、GCD

今天我来详细介绍一下多线程的用法 包括线程整个的生命周期等等

1.0 NSThread 三种表现形式 详情看下面

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"打印当前线程%@",[NSThread currentThread]);
    
    // 1. NSThread
    // NSThread 线程有三种表现形式
    // 1.1 创建对象  需要手动开启线程
    NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(CommonSelector1) object:@"abc"];
    [thread start];
    
    // 1.2 从主线程中分离出一个线程 不需要手动开启
    [NSThread detachNewThreadSelector:@selector(CommonSelector2) toTarget:self withObject:@"abc"];
    
    // 1.3 从后台开辟一个线程
    [self performSelectorInBackground:@selector(CommonSelector3) withObject:@"abc"];
}

-(void)CommonSelector1{
    NSLog(@"打印当前线程----CommonSelector1 = %@",[NSThread currentThread]);
}

-(void)CommonSelector2{
    NSLog(@"打印当前线程----CommonSelector2 = %@",[NSThread currentThread]);
}

-(void)CommonSelector3{
    NSLog(@"打印当前线程----CommonSelector3 = %@",[NSThread currentThread]);
}
// 打印结果
2017-06-01 15:54:32.580 IOS-多线程2[10320:231085] 打印当前线程{number = 1, name = main}
2017-06-01 15:54:32.581 IOS-多线程2[10320:231163] 打印当前线程----CommonSelector1 = {number = 3, name = (null)}
2017-06-01 15:54:32.581 IOS-多线程2[10320:231164] 打印当前线程----CommonSelector2 = {number = 4, name = (null)}
2017-06-01 15:54:32.583 IOS-多线程2[10320:231165] 打印当前线程----CommonSelector3 = {number = 5, name = (null)}

2.0 GCD 这个好玩 这个复杂

2.1 异步async 下 dispatch_get_global_queue 与dispatch_get_main_queue 执行顺序

    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"在主队列中执行任务时不会开启新的线程的");
    });
    // dispatch_get_global_queue 队列的优先级  DISPATCH_QUEUE_PRIORITY_HIGH  高中低
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^{
        
        for (int i = 0; i<5; i++) {
            
            NSLog(@"--5--%@",[NSThread currentThread]);
        }
    });
    // dispatch_get_global_queue 队列的优先级  DISPATCH_QUEUE_PRIORITY_HIGH  高中低
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^{
        for (int i = 0; i<5; i++) {
            NSLog(@"--4--%@",[NSThread currentThread]);
        }
    });
//  输出结果
2017-06-04 12:17:10.381 NSOperation[2767:52779] --5--{number = 4, name = (null)}
2017-06-04 12:17:10.381 NSOperation[2767:52776] --4--{number = 3, name = (null)}
2017-06-04 12:17:20.249 NSOperation[2767:52779] --5--{number = 4, name = (null)}
2017-06-04 12:17:20.250 NSOperation[2767:52776] --4--{number = 3, name = (null)}
2017-06-04 12:17:22.807 NSOperation[2767:52776] --4--{number = 3, name = (null)}
2017-06-04 12:17:22.807 NSOperation[2767:52779] --5--{number = 4, name = (null)}
2017-06-04 12:17:27.115 NSOperation[2767:52717] 在主队列中执行任务时不会开启新的线程的

2.2 注意一种情况

// 这种情况下 只会输出  NSLog(@"1");  然后程序crash 这是一个死锁
    NSLog(@"1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"在主队列中执行任务时不会开启新的线程的");
    });
    NSLog(@"2");

3.0 GCD 的总结

        1. dispatch_queue_t queue = dispatch_queue_create("queue", NULL);
           1.1> 串行队列不论是在sync 还是 async 中 执行任务 任务是依次进行的  但是在async 开启了新的线程
     
        2. dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);
           2.1> 并行队列在sync 中不回开启新的线程 在 async 中会开启新的线程
     
        3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
           3.1> 全局队列在sync 中不会开启新的线程 在 async 中会开启新的线程
     
        4. 在async 中 如果 dispatch_get_main_queue 与 dispatch_get_global_queue 同时存在
           4.1> 执行的先后顺序是 先执行 dispatch_get_global_queue 然后执行 dispatch_get_main_queue

        5. 在dispatch_get_main_queue 添加sync 任务会造成死锁 
           在dispatch_get_main_queue 添加async 任务不会造成卡死 不会开启新的线程 任务是逐次完成的

线程的生命周期

   /*
       线程的生命周期
       1. 首先我们会创建一个线程的对象 并将这个对象放到内存中
       2. 然后我们开启线程,那么此时线程会被放倒内存池中,线程处于 准备被调用状态。等待CPU调度
       3. 当CPU 调度该线程  处于线程调度状态 (这里提一个多线程同时调度)
          当CPU 调度其他线程的时候 该线程处于 被调度状态
       4. 线程阻塞:调度sleep/等待线程阻塞时
       5. 线程的死亡:1.线程任务执行完成 自动死亡 2.线程异常/或者强制退出
   
    
       // 关于线程这一块,不建议用互斥锁 占内存 容易造成死锁
       互斥锁 是在一段时间内锁这线程 使其他线程不能访问 会占用大量的内存 不建议用
    */

NSOperation

我在工程中介绍了 NSOperation 的两种形式 还有一种自定义的没写,因为写了也没什么卵用 做项目根本 就不会用到

所有的代码都放在github: https://github.com/tianbinbin/GCD-NSThread-NSOperation 喜欢的麻烦点个赞

你可能感兴趣的:(多线程NSThread、NSOperation、GCD)