一. 名词解释:

1. 进程和线程

进程是指在系统中正在运行的一个应用程序.每个进程之间都是独立的,每个进程均运行在期专用而且受到保护的内存空间中.

线程是指一个进程想要执行任务,就必须要有线程.线程是进程的基本单元,一个进程的所有任务都在线程中进行.

2. 具体的对多线程的描述请看 文顶顶大神的博客.http://www.cnblogs.com/wendingding/p/3805088.html

二. 队列

/** 队列: 用于存放任务.分为:串行队列和并行队列.
1. 串行队列: 放到串行队列中的任务,GCD会FIFO(先进先出)的取出来一个,执行一个,然后取出来下一个,这样一个一个的执行.
2. 并行队列: 放到并行队列中的任务,GCD也会FIFO的取出来,但不同的是,他取出来一个任务就会放到别的线程中,然后取出来一个又放到另一个线程中.由于取的动作很快,可以忽略不计,看起来,所有的任务都是一起执行的.不过需要注意,GCD会根据系统资源控制并行的数量.所以任务很多也不会然所有的任务都执行.
*/

三. 任务

/** 任务: 有两种执行方式,同步执行和异步执行.区别是是否会创建新的线程.
1. 同步执行(sync): 会阻塞当前的线程并等待Block执行完毕,然后当前线程才会继续往下运行.
2. 异步执行(async): 当前线程会直接往下执行,它不会阻塞当前线程.
*/

四.

    /** 获取主线程
1. 所有的刷新UI界面的任务都要在主线程执行.
2. 将消耗时间的任务放在别的线程中出来,尽量不要在主线程中处理.
*/
dispatch_queue_t main_queue = dispatch_get_main_queue();
NSLog(@"main_queue:\n %@",main_queue); /** 自己创建的队列 dispatch_queue_create
参数1: 第一个参数是标识符.用于DEBUG的时候标志唯一的队列,可以为空.
参数2: 第二个参数用来表示创建的队列是串行的还是并行的.传入DISPATCH_QUEUE_SERIAL或者NULL表示创建的是串行队列.传入DISPATCH_QUEUE_CONCURRENT表示创建的并行队列. (SERIAL--> serial连续的/CONCURRENT--> concurrent,并发的,一致的)
*/ // 创建串行队列
dispatch_queue_t serialQueue = dispatch_queue_create(nil, NULL);
NSLog(@"serialQueue:\n %@",serialQueue); // 创建并行队列: 这应该是唯一一个并行队列,只要是并行任务一般都加入到这个队列
dispatch_queue_t concurrentQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
NSLog(@"concurrentQueue:\n %@",concurrentQueue); // 创建任务
/** 同步任务 (sync)
1. 不会另外开辟线程.
*/
dispatch_sync( serialQueue, ^{ for (int i = ; i < ; i ++)
{
NSLog(@"同步任务: \n%@",[NSThread currentThread]);
}
}); /** 同步任务 (async)
1. 会另外开辟线程.
*/
dispatch_async(serialQueue, ^{
NSLog(@"异步任务: %@",[NSThread currentThread]);
});

五. 例子介绍

NSLog(@"之前==> %@",[NSThread currentThread]);

    dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"sync==> %@",[NSThread currentThread]);
}); NSLog(@"之后==> %@",[NSThread currentThread]); /** 解释
1. 只会打印第一句:之前==> <NSThread: 0x7fe66b700610>{number = 1, name = main} ,然后主线程就卡死了,你可以在界面上放一个按钮,你就会发现点不了了。
2. 打印完第一句,dispatch_sync(因为是一个同步任务,会阻塞当前的线程)会阻塞当前的主线程,然后把Block中的任务放到main_queue中,main_queue中的任务会被取出来放到主线程中执行,但主线程种鸽时候已经被阻塞了,所以Block种鸽的任务就不能完成,它不完成,dispatch_sync就会一直阻塞主线程.导致主线程一直卡死.这就是死锁现象.
*/
 dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

    NSLog(@"输出1.之前==> %@",[NSThread currentThread]);

    dispatch_async(queue, ^{

        NSLog(@"输出2.sync之前==> %@",[NSThread currentThread]);

        dispatch_sync(queue, ^{

            NSLog(@"输出3.sync==> %@",[NSThread currentThread]);
});
NSLog(@"输出4.sync之后==> %@",[NSThread currentThread]);
}); NSLog(@"输出5.之后==> %@",[NSThread currentThread]); /** 解释
1. 当前线程为默认的主线程
2. 输出结果为,输出1,输出5和输出2 执行了输出.输出3和输出4没有被执行.
3. 按照执行顺序分析.
(1)我们创建的队列queue是一个串行队列(DISPATCH_QUEUE_SERIAL).串行队列的特点是,所持有的任务会取出一个执行一个.当前任务没有执行完,下一个任务不会被执行.
(2)打印出输出1.
(3)在queue队列中开启了一个异步任务(async).异步任务的特点是,当前的线程不会被阻塞.所以有了两条线程,一条是主线程中执行输出5.另一条是在新开辟的queue线程中执行输出2.
(4)在开辟的queue线程中,又执行了一个同步的任务(sync),同步任务的特点是执行一个任务会阻塞当前的线程.当前的线程是queue,已经被阻塞了.又要求它去执行下一个任务.就造成了死锁现象.所以 sync 所在的线程被卡死了,输出3和输出4自然就不会打印了.
*/

六.队列组可以将很多队列添加到一个组里,这样做的好处是,当这个组里所有的任务都执行完了,队列组会通过一个方法通知我们。

    //1. 创建队列组
dispatch_group_t group = dispatch_group_create(); //2. 创建队列 dispatch_get_global_queue 会获取一个全局队列,我们姑且理解为系统为我们开启的一些全局线程。我们用priority指定队列的优先级,而flag作为保留字段备用(一般为0)。 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); //3. 多次使用队列中的方法执行任务,只有异步任务
//3.1 执行三次循环
dispatch_group_async(group, queue, ^{ for (int i = ; i < ; i ++)
{
NSLog(@"group-01 - %@",[NSThread currentThread]);
}
}); //3.2 主队列执行8次循环
dispatch_group_async(group, dispatch_get_main_queue(), ^{ for (int i = ; i < ; i ++)
{
NSLog(@"group-02 - %@",[NSThread currentThread]);
}
}); //3.3 执行5次循环
dispatch_group_async(group, queue, ^{ for (int i = ; i < ; i ++)
{
NSLog(@"group-03 - %@",[NSThread currentThread]);
}
}); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"完成 - %@",[NSThread currentThread]);
});

iOS-多线程-GCD的更多相关文章

  1. iOS多线程 GCD

    iOS多线程 GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main que ...

  2. iOS 多线程GCD的基本使用

    <iOS多线程简介>中提到:GCD中有2个核心概念:1.任务(执行什么操作)2.队列(用来存放任务) 那么多线程GCD的基本使用有哪些呢? 可以分以下多种情况: 1.异步函数 + 并发队列 ...

  3. iOS 多线程 GCD part3:API

    https://www.jianshu.com/p/072111f5889d 2017.03.05 22:54* 字数 1667 阅读 88评论 0喜欢 1 0. 预备知识 GCD对时间的描述有些新奇 ...

  4. ios多线程-GCD基本用法

    ios中多线程有三种,NSTread, NSOperation,GCD 这篇就讲讲GCD的基本用法 平时比较多使用和看到的是: dispatch_async(dispatch_get_global_q ...

  5. iOS多线程——GCD与NSOperation总结

    很长时间以来,我个人(可能还有很多同学),对多线程编程都存在一些误解.一个很明显的表现是,很多人有这样的看法: 新开一个线程,能提高速度,避免阻塞主线程 毕竟多线程嘛,几个线程一起跑任务,速度快,还不 ...

  6. iOS多线程GCD的使用

    1. GCD 简介 Grand Central Dispatch(GCD)是异步执行任务的技术之一.一般将应用程序中记述的线程管理用的代码在系统级中实现.开发者只需要定义想执行的任务并追加到适当的Di ...

  7. iOS多线程GCD详解

    在这之前,一直有个疑问就是:gcd的系统管理多线程的概念,如果你看到gcd管理多线程你肯定也有这样的疑问,就是:并发队列怎么回事,即是队列(先进先出)怎么会并发,本人郁闷了好久,才发现其实cgd管理多 ...

  8. iOS多线程GCD的简单使用

    在iOS开发中,苹果提供了三种多线程技术,分别是: (1)NSThread (2)NSOperation (3)GCD 简单介绍一下GCD的使用. GCD全称 Grand Central Dispat ...

  9. iOS多线程——GCD篇

    什么是GCD GCD是苹果对多线程编程做的一套新的抽象基于C语言层的API,结合Block简化了多线程的操作,使得我们对线程操作能够更加的安全高效. 在GCD出现之前Cocoa框架提供了NSObjec ...

  10. iOS 多线程GCD简介

    一.简介 1.1 GCD (Grand Central Dispatch )是Apple开发的一个多核编程的解决方法. Grand 含义是“伟大的.宏大的”,Central含义“中央的”,Dispat ...

随机推荐

  1. android: 文件存储

    数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑 关机的情况下,这些数据仍然不会丢失.保存在内存中的数据是处于瞬时状态的,而保存在 存储设备中的数据是处于持久状态的,持久化 ...

  2. IOS适配

    • Default.png(图片尺寸为320x480):显示在非Retina-3.5英寸屏幕上(iPhone3G\iPhone3GS,屏幕分辨率为320x480) • Default@2x.png(图 ...

  3. LeetCode:Substring with Concatenation of All Words (summarize)

    题目链接 You are given a string, S, and a list of words, L, that are all of the same length. Find all st ...

  4. java产生随机数的几种方式

    java产生随机数的几种方式 一.在j2se里我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,我们可以把他乘以一定的数,比如说乘以100,他 ...

  5. CountDownLatch线程阻塞用法实例

    在编写多线程的工作中,有个常见的问题:主线程(main) 启动好几个子线程(task)来完成并发任务,主线程要等待所有的子线程完成之后才继续执行main的其它任务. 默认主线程退出时其它子线程不会停, ...

  6. UML 六种关系

    .继承, 男人 和 人 的关系2.实现, 孕妇 和 生宝宝 的关系3.依赖, 人 和 大米.水4.关联, 男人 和 工作5.聚合, 弱整体和部分, 轮子和车6.组合, 强整体和部分, 眼睛和人 参考: ...

  7. 修改 Semantic UI 的默认字体

    Semantic UI 默认使用的是谷歌提供的字体,并且是直接使用了谷歌的官方链接.由于大家都知道的原因,谷歌网站在国内访问速度很差,甚至根本无法访问,还有就是可能会在离线环境下使用 Semantic ...

  8. Swift:如何判断一个对象是否是某个类(或其子类)的实例

    在OC中我们直接可以用如下方法即可 [obj  isKindOfClass:[obj class]]; 在Swift中,并没有 .class 属性或者方法, 便可以用如下方法 class Person ...

  9. 更新iOS Distribution Certificates

    1. 鑰匙圈存取 -> 憑證輔助程式 -> 從憑證授權要求憑證 email:xxx@xxxx 得到 Blia_20140129.certSigningReques 2.進入開發帳號 憑證 ...

  10. rbenv Your user account isn't allowed to install to the system Rubygems

    Clone一个新Rails项目到Mac, bundle install 的时候遇到下面的提示 Fetching source index from http://rubygems.org/ Your ...