zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    linux 安装Python3
    MYSQL 字符集设置(终端的字符集)
    Linux LVM Logical Volume Management 逻辑卷的管理
    oracle 重命名和重定位数据文件(Oracle Renaming and Relocating Datafiles)
    Azkaban编译
    基于hive的transform实现自定义分隔符数据导出
    MapReduce优化设置
    hive.groupby.skewindata环境变量与负载均衡
    hive的基本操作
    Shell 数组的定义和使用
  • 原文地址:https://www.cnblogs.com/jerryspace/p/15303875.html
Copyright © 2011-2022 走看看