美文网首页
《高性能 iOS 应用开发》阅读笔记(四)并发编程

《高性能 iOS 应用开发》阅读笔记(四)并发编程

作者: ZhaoXianSheng | 来源:发表于2018-01-30 23:41 被阅读5次

一.线程与内存

1.一个线程内核空间:1kb
2.一个线程栈空间:主线程 1M,子线程 512KB

二.线程与时间

1.创建时间:4~5毫秒
2.启动时间:平均29毫秒
3.总结:开启多个线程非常耗时间
4.GCD上线 64个

三.对比

1.GCD

(1)简单,方便
(2)可以设置栅栏
(3) 不用手动管理

2.NSOperation

(1)面向对象(国外使用较多)
(2)优先级
(3)可以取消,挂起
(4)可以手动管理线程(挂起,取消)
(5)wait
(6)多核安全

3.NSThread

(1).最大程度控制
(2).优先级
(3)麻烦,需要自己枷锁

四. 原子属性一定安全?

一下是我自己写的例子

{
        p.name = "张三"
                | B线程(*2)
        p.name = "李四"
        
        | A线程(*1)
        print(p.name)
}

不安全步骤:
(1)语境:A,B 线程同时 执行这个代码块
(2)A线程走到 *1 处挂起,执行B线程
(3)B线程 走到 *2 处挂起,执行 A线程
(4)这个时候A线程打印 出来的是 "张三",但是我们期望的却是"李四",线程不安全

五.保证线程安全

(1) synchronized

 @synchronized (xxx) {
        p.name = "张三"
                
        p.name = "李四"
        
       
        print(p.name)
    }

(2)NSLock
(3)NSRecursiveLock 允许锁定好多次,适用场景:多个方法同一个锁同步。

  - (void)a1{
      [self.lock lock];
      [self a2];
      [self.lock unlock];
}
- (void)a2{
    [self.lock lock];
     //  code
    [self.lock unlock];
  
}

(4)NSCondition
作用:解决生产者消费这问题。大概用法:当两个线程适用同一个NSCondition加锁时,比如A线程 生产完一个产品,signal、unlock后,会唤醒B线程进行消费。

六.并发读写问题

(1)atomic 只允许一条线程进行读或写,不允许多个线程同时访问这个属性,弊端:有时候需要允许并行读,不允许并行改,这个时候会严重影响性能
(2)高吞吐量并发安全读写:本质上允许并行读取,写入互斥.伪代码

- (id)getMethod{
    __block id rv = nil
    dispatch_async(self.queue, ^{
        nil = @"";
    })
  return nil;
}
- (void)setMethod:(id)obj{
    dispatch_barrier_async(self.queue, ^{
        //code
    })
}

七 多参初始化器 initWithParam :(id)Param :(id)Param :(id)Param :(id)Param :(id)Param .....N个参数

问题:参数太多,向下兼容问题,加入再多一个,还要再加。
解决方案:生成器模式

@implementation User
+ (instancetype)userWithBlock:(void(^)Builder)block{
    Builder *b = [Builder new];
    block(b); -> //(1) 用户 设置 b的属性,相当于传入初始化值
    return [b build];
}
- (instancetype) initWithBuilder:(Builder *)b{
      self.x = b.x //(4)
      .......
}
@implementation Builder
- (User *) build{
  return [[User alloc]initWithBuilder:self];//(3)
}

如何使用(获取User),已注明这段代码调用顺序

User *u = [User  userWithBlock:^(b){
       b.x = @"";//赋值 (2)
}];

(1)调用类方法
(2)让用户传值
(3)调用Builder方法 生成User
(4)User 根据Builder 创建自己对象

八.冰棒不可变

总而言之:前期可变,后期不可变。伪代码

- (void)setxxx:(id)obj{
    if(!bukebian){
        _x = obj;
    }
}

九 函数响应式编程,自行网上找资料,这里只是告诉你有这个东西,什么用,详细用法github。

十 死锁

1.主线程徒步
2.同一个线程多个同步。

相关文章

网友评论

      本文标题:《高性能 iOS 应用开发》阅读笔记(四)并发编程

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