多线程知识总结

多线程的主要作用
  • 显示/刷新UI界面
  • 处理UI事件(比如点击事件、滚动事件、拖拽事件等)
  • 注意:1.别将比较耗时的操作放到主线程.2.耗时操作会卡住主线程,验证影响UI的流畅度,给用户一种很"卡"的感觉

简单的开启线程

//创建一个NSThread线程
-(void)createThreadOne
{
    //object为传进去的参数 可不传
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(go:) object:nil];
    [thread start];
}

/**
 *  创建线程后自动启动,该线程一启动就会执run方法并传进参数rose
 */
-(void)createThreadTwo
{
    [NSThread detachNewThreadSelector:@selector(go:) toTarget:self withObject:@"Two"];
}

/**
 *  创建一个后台执行的线程(隐式线程并启动)
 */
-(void)createThreadThree
{
    [self performSelectorInBackground:@selector(go:) withObject:@"Three"];
    
}

-(void)go:(NSString*)go
{
    NSLog(@"----run--%@",go);
    //让线程睡2秒钟再执行后面的方法
    [NSThread sleepForTimeInterval:2];
//    [NSThread exit]//退出当前线程
    NSLog(@"----run--%@",go);
}

原子核非原子属性的选择

  • atomic :线程安全,需要消耗大量的资源
  • nonatomic :非线程安全,适合内存小的移动设备(属性声明全部用nonatomic)

GCD知识小结

异步 queue:队列 block:任务
dispatch_async(参数1:队列, 参数2:任务)
queue:队列(分两种,串行和并发)

  • 并发队列:可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
  • 并发队列只有在异步函数下才有效(dispatch_async)
    //同步(在当前线程中执行任务,不具备开启新线程的功能)
    dispatch_sync(参数1:队列, 参数2:任务)

同步和异步、并发和串行的区别

(能不能开启新的线程)
同步 :只是在当前线程中执行任务,不具备开启新线程的能力
异步 :可以在新的线程中执行任务,具备开启新线程的能力
(任务执行的方式)
并发 :允许多个任务并发(同时)执行.#注意 :只有在异步函数dispatch_async下才有效
串行 :一个任务执行完毕后,再执行下一个任务

创建队列 其中第一个参数 是个label,一般约定俗成,第二个参数是队列的类型 即同时还是顺次
dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);
DISPATCH_QUEUE_CONCURRENT :同时,即并发队列
DISPATCH_QUEUE_SERIAL :顺次,即串行队列(可传NULL)

各种线程的组合

1.异步 + 串行
/**
 *  异步函数 + 串行队列 :会开启新的线程,但是任务是串行的,执行完一个任务,再执行下一个任务
 */
-(void)asyncSerial
{
    //1.创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.apple.queue", DISPATCH_QUEUE_SERIAL);
    
    //2.将任务加入队列
    dispatch_async(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}

执行该方法的输入结果是


异步函数 + 串行队列.png
2. 异步 + 并发
/**
 *  异步函数 + 并发队列 : 开启新线程,多个任务同时执行
 */
-(void)asyncConcurrent
{
    //1.获取全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.将任务加入队列
    dispatch_async(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}

执行该方法的输入结果是


异步函数 + 并发队列
3.同步 + 串行
/**
 *  同步函数 + 串行队列 :不会开启新线程,任务在当前线程中一个一个执行
 */
-(void)syncSerial
{
    //1.创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.apple.queue", DISPATCH_QUEUE_SERIAL);
    
    //2.将任务加入队列
    dispatch_sync(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}

执行该方法的输入结果是


同步函数 + 串行队列
4.同步 + 并发
/**
 *  同步函数 + 并发队列 :不会开启新线程(并发只有在多线程下才有效果) 
*/
-(void)syncConcurrent
{
    //1.获取全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.将任务加入队列
    dispatch_sync(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}

执行该方法的输入结果是


同步函数 + 并发队列
/**
 *  异步函数 + 主队列 :只在主线程中执行任务
 */
-(void)asyncMain
{
    //1.获得主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    //2.将任务加入队列
    dispatch_async(queue, ^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
}

执行该方法的输入结果是


异步+主线程
并发队列 手动创建的串行队列 主队列
同步(sync) 没有开启新线程、串行执行任务 没有开启新线程、串行执行任务 没有开启新线程、串行执行任务
异步(async) 有开启新线程、并发执行任务 有开启新线程、串行执行任务 没有开启新线程、并发执行任务

GCD常用函数

  • dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    作用:在前面的的任务执行结束后它才执行,而他后面的任务需要等他执行完毕后才会执行(注意:此时的queue不能是全局的并发队列)
    注意:使用dispatch_barrier_async,该函数只能搭配自定义并行队列 dispatch_queue_t使用。不能使用dispatch_get_global_queue,否则 dispatch_barrier_async的作用会和 dispatch_async的作用一模一样。

你可能感兴趣的:(多线程知识总结)