iOS多线程学习

1. GCD的API

/**
 serial(连续的)
 dispatch(分派)
 serialDispatch 一个线程,同时执行的处理只能有一个,按顺序执行
 */
void test_serialDispatch(){
    dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);

    void(^blk_0)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_1)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_2)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_3)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_4)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_5)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_6)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_7)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    dispatch_async(mySerialDispatchQueue, blk_0);
    dispatch_async(mySerialDispatchQueue, blk_1);
    dispatch_async(mySerialDispatchQueue, blk_2);
    dispatch_async(mySerialDispatchQueue, blk_3);
    dispatch_async(mySerialDispatchQueue, blk_4);
    dispatch_async(mySerialDispatchQueue, blk_5);
    dispatch_async(mySerialDispatchQueue, blk_6);
    dispatch_async(mySerialDispatchQueue, blk_7);
    //    dispatch_release(mySerialDispatchQueue);
    NSLog(@"%s,%d",__func__,__LINE__);
}

/**
 concurrent(并发的,同时发生的)
 concurrentDispatch 多个线程,并行执行
 */
void test_concurrentDispatch(){
    dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.example.gcd.MyConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);
    void(^blk_0)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_1)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_2)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_3)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_4)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_5)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_6)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    void(^blk_7)(void) = ^() {
        NSLog(@"%s,%d",__func__,__LINE__);
    };
    dispatch_async(myConcurrentDispatchQueue, blk_0);
    dispatch_async(myConcurrentDispatchQueue, blk_1);
    dispatch_async(myConcurrentDispatchQueue, blk_2);
    dispatch_async(myConcurrentDispatchQueue, blk_3);
    dispatch_async(myConcurrentDispatchQueue, blk_4);
    dispatch_async(myConcurrentDispatchQueue, blk_5);
    dispatch_async(myConcurrentDispatchQueue, blk_6);
    dispatch_async(myConcurrentDispatchQueue, blk_7);
    //    dispatch_release(myConcurrentDispatchQueue);
    NSLog(@"%s,%d",__func__,__LINE__);
}
void test_Main_Global_DispatchQueue(){

    /**主线程*/
    dispatch_queue_t mainDispachQueue = dispatch_get_main_queue();
    /**高优先级*/
    dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    /**默认优先级*/
    dispatch_queue_t globalDisaptchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    /**低优先级*/
    dispatch_queue_t globalDispatchQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    /**后台优先级*/
    dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
}
/**改变线程的优先级*/
void test_dispatch_set_target_queue(){
    //要变更优先级的dispatch queue
    dispatch_queue_t myserialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
    //目标
    dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_set_target_queue(myserialDispatchQueue, globalDispatchQueueBackground);
}
void test_dispatch_after(){
    /*注意:
     dispatch_after函数并不是在指定时间后执行处理,
     而是在指定时间追加处理到Dispatch Queue
     NSEC_PER_SEC 秒
     NSEC_PER_MSEC 毫秒
     NSEC_PER_USEC 微妙
     */
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_USEC);
    dispatch_after(time, dispatch_get_main_queue(), ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
    NSDate *date = [[NSDate alloc]initWithTimeIntervalSinceNow:5];
    dispatch_after(getDispatchTimeByDate(date), dispatch_get_main_queue(), ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
    NSLog(@"%s %d",__func__,__LINE__);
}
//返回指定日期时间
dispatch_time_t getDispatchTimeByDate(NSDate *date){
    NSTimeInterval interval;
    double second, subsecond;
    struct timespec time;
    dispatch_time_t milestone;

    interval = [date timeIntervalSince1970];
    /*
     modf() 将浮点数分解为整数和小数部分,其原型为:
     double modf (double x, double* intpart);
     */
    subsecond = modf(interval, &second);

    time.tv_sec = second;
    time.tv_nsec = subsecond * NSEC_PER_SEC;

    milestone = dispatch_walltime(&time, 0);

    return milestone;
}

/**
 无论向什么样的Dispatch Queue中追加处理,使用Dispatch Group都可监视这些处理执行的结束.一旦测试到所有处理执行结束,就可将结束的处理追加到Dispatch Queue中
 */
void test_Dispatch_Group(){
    dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_async(queue, ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
    dispatch_async(queue, ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
    dispatch_async(queue, ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
//    notify(通知)
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"done");
    });

}
void test_Dispatch_group_wait(){
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, queue, ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"%s %d",__func__,__LINE__);
    });
    dispatch_group_async(group, queue, ^{
        sleep(4);
        NSLog(@"%s %d",__func__,__LINE__);
    });
    //在Dispatch Group中也可以使用dispatch_group_wait函数仅等待全部处理执行结束
//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    long result = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 3ULL * NSEC_PER_SEC));
    if (result == 0) {
        NSLog(@"属于Dispatch Group的全部处理执行结束");
    }else{
        NSLog(@"属于Dispatch Group的某一个处理还在执行中");
    }
}

/**
 barrier(障碍)
 应用于处理数据的读写问题

 写入处理不可以与其他的写入处理以及包含读取处理的其
 他某些处理并行执行.
 但是,读取处理只是与读取处理并行执行,那么多个并行执
 行就不会发生问题.
 就是说:在写入处理结束之前,读取处理不可执行
 */
void test_dispatch_barrier_async(){
    dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.ForBarrier", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"reading data %d",__LINE__);
    });
    dispatch_async(queue, ^{
        NSLog(@"reading data %d",__LINE__);
    });
    dispatch_async(queue, ^{
        NSLog(@"reading data %d",__LINE__);
    });
    dispatch_async(queue, ^{
        NSLog(@"reading data %d",__LINE__);
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"begin writing data %d",__LINE__);
        sleep(4);
        NSLog(@"end writing data %d",__LINE__);

    });
//    dispatch_async(queue, ^{
//        NSLog(@"begin writing data %d",__LINE__);
//        sleep(4);
//        NSLog(@"end writing data %d",__LINE__);
//    });
    dispatch_async(queue, ^{
        NSLog(@"reading data %d",__LINE__);
    });
    dispatch_async(queue, ^{
        NSLog(@"reading data %d",__LINE__);
    });
}

/**
 asynchronous(异步的)
 synchronous(同步的)
 */
void test_dispatch_sync(){
//    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    dispatch_sync(queue, ^{
//        NSLog(@"同步处理");
//    });

    //死锁
//    dispatch_queue_t queue = dispatch_get_main_queue();
//    dispatch_sync(queue, ^{
//        NSLog(@"Hell world");
//    });
//    dispatch_async(queue, ^{
//        dispatch_sync(queue, ^{
//             NSLog(@"Hell world");
//        });
//    });
    dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
    dispatch_async(queue, ^{
        dispatch_sync(queue, ^{
            NSLog(@"Hell world");
        });
    });
}
void test_Dispatch_Apply(){
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    dispatch_apply(10, queue, ^(size_t index) {
//        NSLog(@"%zu",index);
//    });
    NSArray *array = @[@10, @9, @7, @6, @5, @4, @3, @2, @1];
    dispatch_async(queue, ^{
        dispatch_apply([array count], queue, ^(size_t index) {
            NSLog(@"%zu %@",index, [array objectAtIndex:index]);
        });
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"done");
        });
    });
}

/**
 dispatch_supsend(queue)挂起
 dispatch_resume(queue)回复
 */
void test_dispatch_supsend_dispatch_resume(){
    dispatch_queue_t queue = dispatch_queue_create("com.test.gcd", DISPATCH_QUEUE_SERIAL);
    //提交第一个block,延时5秒打印。
    dispatch_async(queue, ^{
        sleep(5);
        NSLog(@"After 5 seconds...");
    });
    //提交第二个block,也是延时5秒打印
    dispatch_async(queue, ^{
        sleep(5);
        NSLog(@"After 5 seconds again...");
    });
    //延时一秒
    NSLog(@"sleep 1 second...");
    sleep(1);
    //挂起队列
    NSLog(@"suspend...");
    dispatch_suspend(queue);
    //延时10秒
    NSLog(@"sleep 10 second...");
    sleep(10);
    //恢复队列
    NSLog(@"resume...");
//    dispatch_resume(queue);
}

/**
 semaphore(信号)
 */
void test_dispatch_semaphore(){
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    /**
     生成dispatch_semaphore.并将计数初始值设定为1
     保持可访问NSMutableArray类对象的线程同时只能有一个
     */
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

    NSMutableArray *array = [NSMutableArray array];

    for (int i = 0; i < 10000; i++) {
        //一直等待,直到Dispatch Semaphore 的计数值达到大于等于1
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        [array addObject:[NSNumber numberWithInt:i]];
        /*

         */
        dispatch_semaphore_signal(semaphore);
    }
}

/**
 保证函数在应用程序中只执行一次处理
 生成单例对象使用
 */
void test_dispatch_once(){
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"初始化单例");
    });
}
void test_dispatch_io(){
}
void test_timer(){
    NSLog(@"%s",__func__);
    /*指定DISPATCH_SOURCE_TYPE_TIMER, 作成Dispatch Source*/
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    /*
     将定时器设定为15秒后
     不指定为重复
     允许延迟1秒
     */
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 15ULL * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1ULL * NSEC_PER_SEC);
    //指定定时器时间内执行处理
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"wakeup");
        //取消Dispatch Source
        dispatch_source_cancel(timer);
    });
    //指定取消Dispatch Source时处理
    dispatch_source_set_cancel_handler(timer, ^{
        NSLog(@"cancel");
    });
    //启动Dispatch Source
    dispatch_resume(timer);
}
 1. (void)countDownWithTime:(int)time
           countDownBlock:(void (^)(int timeLeft))countDownBlock
                 endBlock:(void (^)())endBlock
{
    __block int timeout = time; //倒计时时间
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
    dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
    dispatch_source_set_event_handler(_timer, ^{
        if(timeout<=0){ //倒计时结束,关闭
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                if (endBlock) {
                    endBlock();
                }
            });
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                timeout--;
                if (countDownBlock) {
                    countDownBlock(timeout);
                }
            });
        }
    });
    dispatch_resume(_timer);
}

2. NSThread

#pragma mark:NSThread
 1. (void)testThread{
    NSString *url = @"http://img4.imgtn.bdimg.com/it/u=2437762035,2994278153&fm=23&gp=0.jpg";
//    [NSThread detachNewThreadSelector:@selector(downLoadData:) toTarget:self withObject:url];
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downLoadData:) object:url];
    [thread start];
}
 2. (void)downLoadData:(NSString *)url{
    NSLog(@"begin download.....");
    for (int i = 0 ; i < 5; i++) {
        sleep(1);
        NSLog(@"download....%d%%",(i+1) * 20);
    }
    NSLog(@"finish download......");
    [self performSelectorOnMainThread:@selector(refreshUI:) withObject:[NSData data] waitUntilDone:YES];
}
 3. (void)refreshUI:(NSData *)data{
    NSLog(@"%s",__func__);
}
 4. (void)test_tickets{
    tickets = 100;
    count = 0;
    theLock = [[NSLock alloc] init];
    // 锁对象
    ticketsCondition = [[NSCondition alloc] init];
    ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    [ticketsThreadone setName:@"Thread-1"];
    [ticketsThreadone start];

    ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    [ticketsThreadtwo setName:@"Thread-2"];
    [ticketsThreadtwo start];
}
 5. (void)run{
    while (TRUE) {
        // 上锁
        //        [ticketsCondition lock];
        [theLock lock];
        if(tickets >= 0){
            [NSThread sleepForTimeInterval:0.09];
            count = 100 - tickets;
            NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]);
            tickets--;
        }else{
            break;
        }
        [theLock unlock];
        //        [ticketsCondition unlock];
    }   
}

3. NSOperation

/**
 使用 NSOperation的方式有两种,
 一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
 另一种是继承NSOperation
 */
-(void)testNSOperation{
    NSString *url = @"http://img4.imgtn.bdimg.com/it/u=2437762035,2994278153&fm=23&gp=0.jpg";
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoadData:) object:url];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [queue addOperation:operation];
}

相关链接:http://blog.jobbole.com/69019/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值