Day08 多线程Thread（网络第06天）


#多线程Thread

##1.NSThread
 
###方法1  类方法     直接执行    
                  
    [NSThread detachNewThreadSelector:@selector(handleEvent:) toTarget:self withObject:nil];

###方法2  可以先创建  等要用时再启动 

     NSThread * thread=[[NSThread alloc]initWithTarget:self selector:@selector(handleEvent:) object:@"我爱你"];
调用方法启动

         [thread start];
优先级 最大是1  最低是0 默认0.5(不建议去调优先级，使用默认)

      thread.threadPriority = 1.0;
      threadDictionary  可设置多个需要传的参数   name  设置名称
      
##2.NSObject 
###方法3   NSObject里的方法   

    [self performSelectorInBackground:@selector(handleEvent:) withObject:@"我爱你"];
  
  
##3. NSOperation
###方法4 NSOperation  

    NSOperation * op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(handleEvent:) object:@"传的值"];
    
###方法5（id<> *account  遵循某种协议  注意定义个属性 类型写成 父类 后面在写成所用的子类）
    NSOperation * op = [NSBlockOperation blockOperationWithBlock:^{
 
        sleep(5);
        NSLog(@"完成");
    }];
   同步执行   阻塞
   
    [op start];

###NSOperationQueue

      //请求 放入一个队列里去执行  mainQueue 主线程    alloc ]init]重新设置个队列
     NSOperationQueue * queue = [[NSOperationQueue alloc] init];
     
     
  
   设置最大队列  并行数量
   
    [queue setMaxConcurrentOperationCount:10];
    //异步执行
    [queue addOperation:op];
    
    
##4. GCD

###方法6 GCD  第一个参数0 正常 2最高 -2最低  第二个参数预留

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //操作
        [self handleEvent:@"GCD"];
        dispatch_async(dispatch_get_main_queue(), ^{
            //刷新页面
        });
    });

###线程方法
//调用方法
-(void)handleEvent:(id) obj{

    sleep(5);
    //休眠5S
    [NSThread sleepForTimeInterval:5];
    
    //休眠到一个指定时间   （不休眠后进入一个就绪状态，等待CPU调用）
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]];
    
    NSLog(@"handleEvent处理完:%@",obj);
   }
   
   
#线程同步 

多线程下几个线程多次调用  为了使线程同步

##方式1  NSLock

@property (nonatomic , strong) NSLock * theLock;//锁  同步（再重写init方法里初始化）

    // 显示的锁 相应的lock里有一些方法  方便好用 
    [self.theLock lock];
     //  （  执行的操作代码）
    [self.theLock unlock];


##方式2 @synchronized
        // 隐示加锁
    @synchronized(self){
      （执行的操作代码）
       }

#单例

@implementation Singleton
-(instancetype)init{

    @throw [NSException exceptionWithName:@"Slingleton" reason:@"不能调用单例类的初始化方法" userInfo:nil];
}

-(instancetype)initPrivate {

    if (self = [super init]) {
        self.value = arc4random();
    }
    return self;
}

+(instancetype)sharedInstance{

    static Singleton * instance = nil;
    //只能执行一次
    static dispatch_once_t token;
    dispatch_once(&token,^{
        instance = [[self alloc] initPrivate];
    });
    return instance;
}
@end

###在指定的时间之后执行：

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PE R_SEC);
    dispatch_after(time, queue, ^{});


###多个任务完成后刷新主界面的示例：
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0); 
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{}); 
    dispatch_group_async(group, queue, ^{}); 
    dispatch_group_async(group, queue, ^{}); 
    dispatch_group_notify(group,dispatch_get_main_queue(), ^{}); 
    dispatch_release(group); 

###同时进行读写操作的示例：  （先执行完上面  在执行（中间） 下面）
    dispatch_async(queue, ^{}); 
    dispatch_async(queue, ^{}); 
    dispatch_async(queue, ^{}); 
    dispatch_barrier_async(queue, ^{}); 
    dispatch_async(queue, ^{}); 
    dispatch_async(queue, ^{}); 

###挂起和恢复派发队列
    dispatch_suspend(queue); 
    dispatch_resume(queue);

###只执行一次处理
    static dispatch_once_t token; 
    dispatch_once(&token, ^ {});

##线程安全
###ios多线程开发的建议：
1.所有属性的声明为nonatomic
2.尽量避免多个线程竞争统一资源的情况
3.让服务器端处理复杂逻辑，客户端只获取结果

##(MyNetLib工程)网络封装