iOS 多线程

队列:
在使用GCD的时候,我们会把需要处理的任务放到Block中,然后将任务追加到相应的队列里面,这个队列,叫做Dispatch Queue。然而,存在于两种Dispatch Queue,一种是要等待上一个执行完,再执行下一个的Serial Dispatch Queue,这叫做串行队列;另一种,则是不需要上一个执行完,就能执行下一个的Concurrent Dispatch Queue,叫做并行队列。
队列:可以理解为存放任务的容器

  1. 系统标准提供的两个队列
    // 全局队列,也是一个并行队列
    dispatch_get_global_queue
    // 主队列,在主线程中运行,因为主线程只有一个,所以这是一个串行队列
    dispatch_get_main_queue
  2. 除此之外,还可以自己生成队列
    // 从DISPATCH_QUEUE_SERIAL看出,这是串行队列
    dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL)
    // 同理,这是一个并行队列
    dispatch_queue_create("com.demo.concurrentQueue", DISPATCH_QUEUE_CONCURRENT)

同步与异步

串行与并行针对的是队列,而同步与异步,针对的则是线程。最大的区别在于,同步线程要阻塞当前线程,必须要等待同步线程中的任务执行完,返回以后,才能继续执行下一任务;而异步线程则是不用等待。
同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕!
如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。

GCD跑几个方法 结果一目了然

/**
 *  async -- 并发队列(最常用)
 *  会不会创建线程:会,一般同时开多条
 *  任务的执行方式:并发执行
 */
- (void)asyncGlobalQueue
{
    // 获得全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 将 任务 添加 全局队列 中去 异步 执行
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}

/**
 *  sync -- 并发队列
 *  会不会创建线程:不会,当前线程中执行
 *  任务的执行方式:串行执行
 */
- (void)syncGlobalQueue
{
    // 获得全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 将 任务 添加 全局队列 中去 异步 执行
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    
    
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}


/**
 *  async -- 串行队列(有时候用)
 *  会不会创建线程:会,一般只开1条线程
 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
 */
- (void)asyncSerialQueue
{
    // 1.创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
    
    // 2.将任务添加到串行队列中 异步 执行
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}


/**
 *  sync 同步执行 -- 串行队列
 *  会不会创建线程:不会,当前线程中执行
 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
 */
- (void)syncSerialQueue
{
    // 1.创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
    
    // 2.将任务添加到串行队列中 异步 执行
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}

/**
 *  async 异步执行 -- 主队列串行队列
 *  会不会创建线程:不会,当前线程中执行
 *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
 */
- (void)asyncMainSerialQueue
{
    // 1.创建一个串行队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 2.将任务添加到串行队列中 异步 执行
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}



/**
 *  sync 同步执行 -- 主队列串行队列
 *  线程死锁
 */
- (void)syncMainSerialQueue
{
    // 1.创建一个串行队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 2.将任务添加到串行队列中 异步 执行
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}
线程死锁
- (void)syncSerialQueue
{
    // 1.创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
    
    // 2.将任务添加到串行队列中 异步 执行
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
        //
        dispatch_sync(queue, ^{
            NSLog(@"-----XXX下载图片1XX---%@", [NSThread currentThread]);
        });
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
    });
    NSLog(@"-----到底---%@", [NSThread currentThread]);
}


http://www.jianshu.com/p/c0e2d96a238e

要求请求A和请求B都都完成拿到结果,再执行C操作。


// *** 利用队列组 ****//
- (void)userGroupMethod
{
    // 创建队列组
    dispatch_group_t myGroup = dispatch_group_create();
    // 创建并发队列
    dispatch_queue_t myQueue = dispatch_queue_create(0, 0);
    // 使用函数添加任务(所有任务都是并发执行)
    /**
     *  任务A
     */
    dispatch_group_enter(myGroup);
    dispatch_async(myQueue, ^{
        // 请求A

        if (success) {
            // 请求成功
            dispatch_group_leave(myGroup);

        }else{
            // 失败
            dispatch_group_leave(myGroup);

        }
    });

    /**
     *  任务B
     */
    dispatch_group_enter(myGroup);
    dispatch_async(myQueue, ^{
        // 请求B

        if (success) {
            // 请求成功
            dispatch_group_leave(myGroup);

        }else{
            // 失败
            dispatch_group_leave(myGroup);

        }
    });

    // A,B执行完毕,不论成功失败。只要执行完毕就执行下方代码
    dispatch_group_notify(myGroup, myQueue, ^{
        // 执行C操作。注意刷新UI等需要回到主线程。
        dispatch_async(dispatch_get_main_queue(), ^{
            // 刷新等操作。
        });

    });
}

你可能感兴趣的:(iOS 多线程)