多线程

作者: 红色海_ | 来源:发表于2019-10-16 16:16 被阅读0次

https://blog.csdn.net/PeaksLee/article/details/78270157

  • NSThread
  • GCD
  • NSOperation & NSOperationQueue
1. NSThread

苹果封装, 完全面向对象。但生命周期需要手动管理.

--------------------------------------
////先创建再启动//////////////////////
--------------------------------------
OBJECTIVE-C
  // 创建
  NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];
  // 启动
  [thread start];
SWIFT
//创建
  let thread = NSThread(target: self, selector: "run:", object: nil)
  //启动
  thread.start()
--------------------------------------
////创建并自动启动//////////////////////////
--------------------------------------
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];

NSThread.detachNewThreadSelector("run:", toTarget: self, withObject: nil)
--------------------------------------
////使用 NSObject 的方法创建并自动启动////////////
--------------------------------------
@interface NSObject (NSThreadPerformAdditions)
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
    // equivalent to the first method with kCFRunLoopCommonModes

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    // equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

@end
///////////////////////////////////////////////////
OBJECTIVE-C
 [self performSelectorInBackground:@selector(run:) withObject:nil];

SWIFT
苹果认为 performSelector: 不安全所以在Swift 去掉了这个方法。
其他方法.............不一一列举了。。
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isCancelled) BOOL cancelled;
2. GCD

苹果为多核的并行提出的解决方案,
合理地利用更多的CPU内核(比如双核、四核),
自动管理线程的生命周期(创建线程、调度任务、销毁线程),
使用的是 c语言,利用了 Block(Swift里叫做闭包),
使用起来更加方便灵活。

GCD 中加入了两个非常重要的概念: 任务 和 队列
任务

即操作 你想要干什么,就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。

任务有两种执行方式: 同步执行 和 异步执行

区别:
是否会创建新的线程。
会不会阻塞当前线程,直到 Block 中的任务执行完毕!

同步(sync) 操作,会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
异步(async)操作,当前线程会直接往下执行,不会阻塞当前线程。

队列:用于存放任务。 串行队列 并行队列。

串行队列的任务: GCD 会 FIFO(先进先出) 地取出来一个,执行一个,然后取下一个,这样一个一个的执行。

并行队列的任务: GCD 也会 FIFO的取出来,但不同的是它取出来一个就会放到别的线程,再取出来一个又放到另一个的线程。这样由于取的动作很快,看起来所有的任务是一起执行的。需要注意GCD 会根据系统资源控制并行的数量,所以如果任务很多它并不会让所有任务同时执行。

创建队列
主队列:这是一个特殊的 串行队列。它用于刷新 UI,

任何需要刷新 UI 的工作都要在主队列执行,
一般耗时的任务都要放到别的线程执行。

  //OBJECTIVE-C
  dispatch_queue_t queue = ispatch_get_main_queue();
  //SWIFT
  let queue = ispatch_get_main_queue()
自己创建的队列: 串行 并行

它有两个参数,第一个参数是标识符,用于 DEBUG 的时候标识唯一的队列,可以为空。第二个才是最重要的。
第二个参数用来表示创建的队列是串行的还是并行的,
DISPATCH_QUEUE_SERIAL 或 NULL 创建串行队列。
DISPATCH_QUEUE_CONCURRENT 创建并行队列。

//OBJECTIVE-C
  //串行队列
  dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL);
  dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL);
  //并行队列
  dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT);
 
  //SWIFT
  //串行队列
  let queue = dispatch_queue_create("tk.bourne.testQueue", nil);
  let queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL)
  //并行队列
  let queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT)
全局并行队列:

只要是并行任务一般都加入到这个队列。这是系统提供的一个并发队列。

//OBJECTIVE-C
  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
  //SWIFT
  let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
创建任务

同步任务: 阻塞当前线程 (SYNC)

OBJECTIVE-C
  dispatch_sync(<#queue#>, ^{
      //code here
      NSLog(@"%@", [NSThread currentThread]);
  });
SWIFT
  dispatch_sync(<#queue#>, { () -> Void in
      //code here
      println(NSThread.currentThread())
异步任务:不会阻塞当前线程 (ASYNC)
OBJECTIVE-C

  dispatch_async(<#queue#>, ^{
      //code here
      NSLog(@"%@", [NSThread currentThread]);
  });
SWIFT

  dispatch_async(<#queue#>, { () -> Void in
      //code here
      println(NSThread.currentThread())
}
为更好的理解 同步,异步,和各种队列的使用,看两个示例:

示例一:
以下代码在主线程调用,结果是什么?

NSLog("之前 - %@", NSThread.currentThread())
dispatch_sync(dispatch_get_main_queue(), { () -> Void in 
        NSLog("sync - %@", NSThread.currentThread())
})
NSLog("之后 - %@", NSThread.currentThread())

答案:
只会打印第一句:之前 - <NSThread: 0x7fb3a9e16470>{number = 1, name = main} ,然后主线程就卡死了,你可以在界面上放一个按钮,你就会发现点不了了。
解释:
同步任务会阻塞当前线程,然后把 Block 中的任务放到指定的队列中执行,只有等到 Block 中的任务完成后才会让当前线程继续往下运行。
那么这里的步骤就是:打印完第一句后,dispatch_sync 立即阻塞当前的主线程,然后把 Block 中的任务放到 main_queue 中,可是 main_queue 中的任务会被取出来放到主线程中执行,但主线程这个时候已经被阻塞了,所以 Block 中的任务就不能完成,它不完成,dispatch_sync 就会一直阻塞主线程,这就是死锁现象。导致主线程一直卡死。

示例二:
以下代码会产生什么结果?

let queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL)
 
   NSLog("之前 - %@", NSThread.currentThread())
 
    dispatch_async(queue, { () -> Void in
        NSLog("sync之前 - %@", NSThread.currentThread())
        dispatch_sync(queue, { () -> Void in
             NSLog("sync - %@", NSThread.currentThread())
        })
        NSLog("sync之后 - %@", NSThread.currentThread())
   })
 
  NSLog("之后 - %@", NSThread.currentThread())

未完 待续。。。

相关文章

  • iOS多线程 NSOperation

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程 pthread、NSThread

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程: GCD

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程运用

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • iOS多线程基础

    系列文章: 多线程 多线程 pthread、NSThread 多线程 GCD 多线程 NSOperation 多线...

  • 多线程介绍

    一、进程与线程 进程介绍 线程介绍 线程的串行 二、多线程 多线程介绍 多线程原理 多线程的优缺点 多线程优点: ...

  • iOS进阶之多线程管理(GCD、RunLoop、pthread、

    深入理解RunLoopiOS多线程--彻底学会多线程之『GCD』iOS多线程--彻底学会多线程之『pthread、...

  • iOS多线程相关面试题

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

  • 多线程之--NSOperation

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

  • iOS多线程之--NSThread

    iOS多线程demo iOS多线程之--NSThread iOS多线程之--GCD详解 iOS多线程之--NSOp...

网友评论

      本文标题:多线程

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