iOS 多线程

#import "JYMoreThread.h"

/**
 http://www.cocoachina.com/articles/19769
 
 */

@implementation JYMoreThread

- (void)setupThread {
    [self syncMain];
}

/** 串行同步 */
- (void)syncSerial {

    NSLog(@"**************串行同步***************");

    // 串行队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    // 同步执行
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"串行同步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"串行同步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"串行同步3   %@",[NSThread currentThread]);
        }
    });
}

/** 串行异步 */
- (void)asyncSerial {

    NSLog(@"**************串行异步***************");

    // 串行队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    // 同步执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"串行异步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"串行异步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"串行异步3   %@",[NSThread currentThread]);
        }
    });
}

/** 并发同步 */
- (void)syncConcurrent {
    
    NSLog(@"**************并发同步***************");
    // 并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    // 同步执行
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"并发同步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"并发同步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"并发同步3   %@",[NSThread currentThread]);
        }
    });
}

/** 并发异步 */
- (void)asyncConcurrent {

    NSLog(@"**************并发异步***************");

    // 并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

    // 异步执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"并发异步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"并发异步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"并发异步3   %@",[NSThread currentThread]);
        }
    });
}

/** 主队列同步 */
- (void)syncMain {

    /**
     主队列同步造成死锁的原因:

     如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。

     而同步对于任务是立刻执行的,那么当把第一个任务放进主队列时,它就会立马执行。

     可是主线程现在正在处理syncMain方法,任务需要等syncMain执行完才能执行。

     syncMain执行到第一个任务的时候,又要等第一个任务执行完才能往下执行第二个和第三个任务。

     这样syncMain方法和第一个任务就开始了互相等待,形成了死锁。
     */
    
    NSLog(@"**************主队列同步,放到主线程会死锁***************");

    // 主队列
    dispatch_queue_t queue = dispatch_get_main_queue();

    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主队列同步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主队列同步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主队列同步3   %@",[NSThread currentThread]);
        }
    });
}

/** 主队列异步 */
- (void)asyncMain {

    NSLog(@"**************主队列异步***************");

    // 主队列
    dispatch_queue_t queue = dispatch_get_main_queue();

    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主队列异步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主队列异步2   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"主队列异步3   %@",[NSThread currentThread]);
        }
    });
}

// GCD栅栏
// 当任务需要异步进行,但是这些任务需要分成两组来执行,第一组完成之后才能进行第二组的操作。这时候就用了到GCD的栅栏方法dispatch_barrier_async。

- (void)barrierGCD {

    // 并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

    // 异步执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏:并发异步1   %@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏:并发异步2   %@",[NSThread currentThread]);
        }
    });

//    dispatch_barrier_async(queue, ^{
//        NSLog(@"------------barrier------------%@", [NSThread currentThread]);
//        NSLog(@"******* 并发异步执行,但是34一定在12后面 *********");
//    });
    
    dispatch_barrier_sync(queue, ^{
        NSLog(@"------------barrier------------%@", [NSThread currentThread]);
        NSLog(@"******* 并发异步执行,但是34一定在12后面 *********");
    });

    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏:并发异步3   %@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"栅栏:并发异步4   %@",[NSThread currentThread]);
        }
    });
}

- (void)barrierGCD22 {
    // 并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);

    // 异步执行
    dispatch_async(queue, ^{
        NSLog(@"栅栏:并发异步1   %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"栅栏:并发异步2   %@",[NSThread currentThread]);
    });
    
//    dispatch_barrier_sync(queue, ^{
//        NSLog(@"++++ barrier sync +++++");
//    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"++++ barrier async +++++");
    });
    
    NSLog(@"洪城河");
    dispatch_async(queue, ^{
        NSLog(@"栅栏:并发异步3   %@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"栅栏:并发异步4   %@",[NSThread currentThread]);
    });
    NSLog(@"last");
}

- (void)applyGCD {

    NSLog(@"************** GCD快速迭代 ***************");

    // 并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    // dispatch_apply几乎同时遍历多个数字
    dispatch_apply(7, queue, ^(size_t index) {
        NSLog(@"dispatch_apply:%zd======%@",index, [NSThread currentThread]);
    });
}

- (void)testGroup {
    /**
     队列组有下面几个特点:

     1、所有的任务会并发的执行(不按序)。

     2、所有的异步函数都添加到队列中,然后再纳入队列组的监听范围。

     3、使用dispatch_group_notify函数,来监听上面的任务是否完成,如果完成, 就会调用这个方法。
     */
    
    dispatch_group_t group =  dispatch_group_create();

    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"队列组1:有一个耗时操作完成!");
    });

    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"队列组2:有一个耗时操作完成!");
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"队列组3:有一个耗时操作完成!");
    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"队列组4:前面的耗时操作都完成了,回到主线程进行相关操作");
    });
}

-(void)dispatchSignal{
    //crate的value表示,最多几个资源可访问
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     
    //任务1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"complete task 1");
        dispatch_semaphore_signal(semaphore);
    });
    //任务2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);
    });
    //任务3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);
    });
    
    //任务4
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 4");
        sleep(1);
        NSLog(@"complete task 4");
        dispatch_semaphore_signal(semaphore);
    });

    //任务5
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 5");
        sleep(1);
        NSLog(@"complete task 5");
        dispatch_semaphore_signal(semaphore);
    });
    //任务6
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 6");
        sleep(1);
        NSLog(@"complete task 6");
        dispatch_semaphore_signal(semaphore);
    });

}

- (void)testNSInvocationOperation {
    // 创建NSInvocationOperation
    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperation) object:nil];
    // 开始执行操作
    [invocationOperation start];
}

- (void)invocationOperation {
    // 打印结果如下,得到结论:程序在主线程执行,没有开启新线程。
    NSLog(@"NSInvocationOperation包含的任务,没有加入队列========%@", [NSThread currentThread]);
}

- (void)testNSBlockOperation {
    // 可以看出:主线程执行,没有开启新线程
    // 同样的,NSBlockOperation可以配合队列NSOperationQueue来实现多线程
    // 把任务放到block中
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation包含的任务,没有加入队列========%@", [NSThread currentThread]);
    }];

    [blockOperation start];
}

- (void)testNSBlockOperationExecution {
    
    /**
     执行结果如下,可以看出,NSBlockOperation创建时block中的任务是在主线程执行,而运用addExecutionBlock加入的任务是在子线程执行的。
     */
    
    // NSBlockOperation有一个方法addExecutionBlock:,通过这个方法可以让NSBlockOperation实现多线程。
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation运用addExecutionBlock主任务========%@", [NSThread currentThread]);
    }];

    [blockOperation addExecutionBlock:^{
        NSLog(@"NSBlockOperation运用addExecutionBlock方法添加任务1========%@", [NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"NSBlockOperation运用addExecutionBlock方法添加任务2========%@", [NSThread currentThread]);
    }];
    [blockOperation addExecutionBlock:^{
        NSLog(@"NSBlockOperation运用addExecutionBlock方法添加任务3========%@", [NSThread currentThread]);
    }];
    [blockOperation start];

}

- (void)testOperationQueue {
    // 创建队列,默认并发
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 创建操作,NSInvocationOperation
    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperationAddOperation) object:nil];
    // 创建操作,NSBlockOperation
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"addOperation把任务添加到队列======%@", [NSThread currentThread]);
        }
    }];

    [queue addOperation:invocationOperation];
    [queue addOperation:blockOperation];
}


- (void)invocationOperationAddOperation {
    NSLog(@"invocationOperation===aaddOperation把任务添加到队列====%@", [NSThread currentThread]);
}

- (void)testAddOperationWithBlock {
    // 创建队列,默认并发
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 添加操作到队列
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"addOperationWithBlock把任务添加到队列======%@", [NSThread currentThread]);
        }
    }];
}

// 运用最大并发数实现串行
- (void)testMaxConcurrentOperationCount {
    // 创建队列,默认并发
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 最大并发数为1,串行
//    queue.maxConcurrentOperationCount = 1;

    // 最大并发数为2,并发
    queue.maxConcurrentOperationCount = 2;


    // 添加操作到队列
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"addOperationWithBlock把任务添加到队列1======%@", [NSThread currentThread]);
        }
    }];
    // 添加操作到队列
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"addOperationWithBlock把任务添加到队列2======%@", [NSThread currentThread]);
        }
    }];

    // 添加操作到队列
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"addOperationWithBlock把任务添加到队列3======%@", [NSThread currentThread]);
        }
    }];
}

- (void)testAddDependency {

    // 并发队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 操作1
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"operation1======%@", [NSThread  currentThread]);
        }
    }];

    // 操作2
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"****operation2依赖于operation1,只有当operation1执行完毕,operation2才会执行****");
        for (int i = 0; i < 3; i++) {
            NSLog(@"operation2======%@", [NSThread  currentThread]);
        }
    }];

    // 使操作2依赖于操作1
    [operation2 addDependency:operation1];
    // 把操作加入队列
    [queue addOperation:operation1];
    [queue addOperation:operation2];
}



@end
原文地址:https://www.cnblogs.com/jerryspace/p/15303875.html