多线程复习

自旋锁 & 互斥锁

自旋锁:
atomic、OSSpinLock、dispatch_semaphore_t
临界区加锁,不解锁一直忙碌不停循环,没有线程切换的时间开销,用于执行频繁访问临界区任务。Runtime引用计数大量使用自旋锁。

互斥锁:
pthread_mutex、 @synchronized、NSLock、NSCondition、NSConditionLock、NSRecursiveLock

临界区加锁,被阻塞线程进入休眠,直到互斥锁释放后才被唤醒,线程开销大,用于不经常切换切耗时的操作。

线程通信

performSelector
NSMachPort
GCD

GCD & NSOperation

GCD

  • 基于C语言的面向内核多线程的技术,用于代替NSthread,发挥CPU多核优势提高CPU效率。
  • 最基本的是dispatchQueue,FIFO队列,
  • 并行Concurrent Queues、串行Serial Queues,同步线程sync、异步线程async
  • 使用简洁,不用考虑底层实现,
  • 很难控制并发异步线程之间的执行顺序和依赖关系
  • 无法终止已经执行的线程

NSOperation

  • 面向对象的多线程技术,是基于GCD的封装,GCD的高级抽象,
  • 配合NSOperationQueue配合使用,
  • 不支持FIFO对列
  • 可以设置线程间优先级和依赖关系,
  • 设置最大并发数,
  • 可以取消未执行线程,但不能终止正在执行线程
    -可以通过KVO观察NSOperation的状态

NSOperation

使用NSOperation子类的方式有三种:

NSInvocationOperation

NSBlockOperation

自定义子类继承NSOperation,实现内部相应的方法
NSOperation其实就是对GCD的一个封装。

创建NSInvocationOperation对象

-(id)initWithTarget:(id) target selector:(SEL)sel object:(id) arg;

调用start方法开始执行操作

-(void)start;

一旦执行操作,就会调用target的sel方法。

注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作。

只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作

创建NSBlockOperation对象

+(id)blockOperationWithBlock:(void (^)(void)) block;

通过addExecutionBlock:方法添加更多的操作

-(void)addExecutionBlock:(void (^)(void)) block;

注意:只要NSBlockOperation封装的操作数>1, 就会异步执行操作。

1 - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 2 {
 3 //    [self opDemo1];
 4 //    [self opDemo2];
 5 //    [self opDemo3];
 6     [self opDemo4];
 7 }
 8 
 9 - (void)down
10 {
11     for (int i = 0; i < 2; i ++) {
12           NSLog(@"%d", i+2);
13     }
14 }
15 
16 #pragma mark - 单个NSInvocationOperation使用
17 - (void) opDemo1
18 {
19     NSLog(@"1");
20     //创建操作
21     NSOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(down) object:@"Invocation"];
22     //直接在当前线程执行(同步执行)【没有开辟线程】
23     [op start];
24     //放到队列gg
25 //    NSOperationQueue * que = [[NSOperationQueue alloc] init];
26 //    //只要把操作添加到队列,就会异步执行任务(但是任务中的任务会顺序执行)【开辟了线程】
27 //    [que addOperation:op];
28     NSLog(@"3");
29 }
30 
31 - (void) opDemo2
32 {
33     NSLog(@"1");
34     /**
35      1.队列(GCD里面的并发(全局)队列使用最多),所以NSOperation技术直接把GCD里面的并发技术封装起来
36      2.NSOperationQueue,本质就是GCD里面的并发队列
37      3.操作是GCD里面的异步执行的任务
38      **/
39     NSOperationQueue * q = [[NSOperationQueue alloc] init];
40     for (int i = 0; i < 2; i ++) {
41         NSOperation * op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(down) object:@"Invocation"];
42         [q addOperation:op];
43     }
44     NSLog(@"4");
45 }
46 
47 - (void) opDemo3
48 {
49     NSLog(@"1");
50     //相当于GCD主队列
51     NSOperationQueue * q = [NSOperationQueue mainQueue];
52     //当NSOpertaion获取主线程,不会在开辟线程,但是里面的任务会在其他主线程任务执行完成后才回归执行
53     for (int i = 0; i < 5; i ++) {
54         
55         NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
56            NSLog(@"%@==========%d", [NSThread currentThread], i);
57         }];
58         //将block放入到队列
59         //block中可以添加多个任务
60         [q addOperation:op];
61     }
62     NSLog(@"6");
63     
64 }
65 66 - (void) opDemo4
67 {
68     NSLog(@"1");
69     NSOperationQueue * q = [[NSOperationQueue alloc] init];
70     //block块中可以写多个任务(里面串行队列),相当于GCD中的并行串行队列
71     NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
72         NSLog(@"2");
73         NSLog(@"3");
74         NSLog(@"4");
75     }];
76     [q addOperation:op];
77     //还可以在外面给队列添加任务.但是遵循fifo
78     [op addExecutionBlock:^{
79         NSLog(@"6");
80         NSLog(@"7");
81     }];
82     NSLog(@"5");
83 }
image.png

你可能感兴趣的:(多线程复习)