【学习总结】【多线程】 多线程概要 & GDC & NSOperation
基本需要知道的 :
进程 : 简单点来说就是,操作系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在受保护的内存空间内
线程 : 一个进程(进程)想执行任务,必须有线程(所以,每个进程至少有1条线程),线程是进程的基本执行单元.
疑问 : 在一条线程中怎样执行任务? 线程的串行
线程的串行 : 一个线程中任务的执行是串行的(同一时间内,1个线程只能执行一个任务,)
疑问 : 哪有耗时操作怎么办?或者需要同时执行几个任务? 多线程
多线程 : 顾名思义,就是在一个进程中,开启多条线程并行执行任务(同时执行任务) -->实质上原理是,CPU飞速在多条线程中之间调度(切换),看起来一起操作
疑问 : 如果线程非常多,会发生什么情况? 1. CPU调度频率高,消耗大量资源 2.每条线程被调度执行次数降低(效率低)
疑问 : 多线程技术的优缺点 ? 优点 : 1. 适当提高程序执行效率, 2.适当提高系统资源利用率 缺点 : 1. 开启太多,会降低程序性能 2. 开启太多,CPU开销大 3.程序设计非常复杂(线程间的通讯,线程的数据共享)
IOS主线程 : (又称UI线程) 主要作用 :1.显示\刷新UI界面 2.处理UI事件(点击事件,滚动事件,拖拽事件)
疑问 : 多线程技术怎么实现? 方案有哪些? 1.NSThread , 2.GCD , 3.NSOperation
NSThread : OC - 程序员管理(手动创建,销毁) - 面向对象
GCD : C - 自动管理(自动创建,销毁) - 面向对象 - 充分利用设备的多核 - 自动管理多线程
NSOperation : OC - 自动管理(自动创建,销毁) - GCD的高级封装
疑问 : 多线程技术的隐患? 1. 多个线程可能会访问同一块资源,容易引发数据错乱和数据安全 - 安全隐患解决(互斥锁)
疑问 : 什么是线程同步? 为什么需要线程同步? 1.线程同步就是多条线程在同一条线上执行 2.有时候避免多条线程访问同一份资源,就需要加锁,加锁的操作就等于将所有线程访问这个资源应该按顺序来执行.(主要是避免引发数据错乱和数据安全)
/*
GCD (Grand Central Dispatch)的两个核心概念
任务 : 执行什么操作
* 用Block来封装任务 队列 : 用来存放任务
* 全局的并发队列 : 可以让任务并发执行 所以 : GCD的使用也就两步 1 -> 确定想做的事情(确定任务) 2 -> GCD会自动将队列中得任务取出, 放到对应的线程中执行
任务的取出遵循队列的FIFO原则: 先进先出 , 后进后出 -------------------------------------队列的创建方式------------------------------------------------- // 两个参数, 前面的参数一般用default ,后面参数默认0,暂时没用
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); * 自己创建的串行队列 : 让任务一个接着一个执行
// 创建队列名称 , dispatch_queue_t类 注意:cn.cwlng.queue 可以任意写.
dispatch_queue_t queue = dispatch_queue_create("cn.cwlng.queue", NULL); * 主队列 : 让任务在主线程执行
// 获取主队列
dispatch_queue_t queue = dispatch_get_main_queue(); ------------------------------------执行任务的函数------------------------------------------------- * 同步执行 : 不具备开启新线程的能力
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>) * 异步执行 : 具备开启新线程的能力
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>) ------------------------------------常见的组合与它们之间的通讯--------------------------------------- * dispatch_async + 全局并发队列 ; * dispatch_async + 自己创建的串行队列; * 线程间的通讯 dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
}); }); ------------------------------------ 延迟执行 ------------------------------------------------- * 一旦定制好延迟任务后, 不会卡住当前线程 performSelector
//afterDelay秒后,执行SEL方法,并传入WithObject参数
[self performSelector:<#(SEL)#> withObject:<#(id)#> afterDelay:<#(NSTimeInterval)#>] * 利用GCD函数执行延迟执行操作 dispatch_after
// 获取默认并发线程 , 注意: 这里获取是并发线程的话,下面就在子线程中执行,如果是主线程,则时间过后,跳回主线程执行操作
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 延迟加载
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
NSLog(@"这里是执行代码的操作"); }); ------------------------------------ 一次性代码 -------------------------------------------------
// 一次性代码
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 这里的代码,在程序运行过程中,永远只会执行一次 }); */ /* 串行队列 创建方式 :
1 -> 使用 dispatch_queue_create函数创建串行队列 // 创建队列名称 , dispatch_queue_t类 注意:cn.cwlng.queue 可以任意写.
dispatch_queue_t queue = dispatch_queue_create("cn.cwlng.queue", NULL); 2 -> 使用主队列(根主线程相关联的队列) 主队列是GCD自带的一种特殊的串行队列
放在主队列中得任务,都会放到主线程中执行 // 获取主队列
dispatch_queue_t queue = dispatch_get_main_queue(); */ /* 释放内存结论
1. 凡是函数名中带有 create \ copy \ new \ retain 等字眼,都应该在不需要使用这个数据的时候进行release
2. GCD的数据类型在ARC环境下不需要再作release
3. CF(Code Foundation)的数据类型在ARC\MRC环境下都需要在做release */
GCD 基本操作
四个术语 : 同步, 异步, 并发 , 串行
同步&异步主要影响能不能开启新的线程
* 同步执行 : 在当前线程中执行任务, 不具备开启新线程的能力
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
* 异步执行 : 在新的线程中执行任务 , 具备开启新线程的能力
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
并发&串行主要影响 : 任务的执行方式
* 并发队列 : 可以让多个任务并发(同时)执行 (其实就是自动开启多个线程同时执行任务)
* 串行队列 : 让任务一个接着一个地执行 (一个任务执行完后,再执行下一个任务)
问问自己:
什么是GDC?
GDC是(Grand Central Dispatch) 其实就是帮助管理多线程的一套API.
既然是一套API,那么GDC怎么管理多线程?
GDC 有两个核心的概念,任务和队列
任务 : 执行怎样的操作.
队列 : 用来存放任务.
-> 所以 利用GDC管理就是,确定想做的事情(确定任务),然后将任务放到队列中,GDC会自动将队列的任务中拿出来执行
GDC从队列中取出任务,是遵循,先进先出的原则的.
那GDC队列的创建方式有哪一些呢?
-> 首先要知道,队列是分两种形式, 并行队列和串行队列.
并行队列 : 任务在并行队列中会同时执行.
串行队列 : 任务在串行任务中会一个任务一个任务地执行.
-> 需要掌握的三种创建队列的方法(这里总结一下,具体方式请看上面代码块)
* 创建并行队列.一般使用Default模式
* 创建自定义的串行队列.
* 创建系统的主队列.
任务添加进去队列后,队列有什么方式去执行任务呢?
* 同步执行 : 不具备开启新线程的能力
dispatch_sync
* 异步执行 : 具备开启新线程的能力
dispatch_async
执行的过程中,很多时候需要线程之间的通讯,怎么实现线程中得通讯呢?
GDC的方法调用非常方便 , 只需要在线程执行的过程中,也就是那个Block代码块里面
添加你需要通讯的那个线程即可,然后GDC会自动调用Block代码块,实现互相通讯
--------------------------------------------------NSOperation多线程--------------------------------------------------------------------------
/*
NSOperation & NSOperationQueue
1. 队列的类型 -> 主队列(同步串行执行)
* [NSOperation mainQueue]
* 添加到"主队列"中的操作,都会放到主线程中执行 -> 非主队列(默认创建即是异步并发执行)
* [[NSOperation alloc] init]
* 添加到"非主队列"中的操作,都会放到子线程中执行 2. 将任务添加到队列中
-> - (void)addOperation:(NSOperation *)op;
-> - (void)addOperationWithBlock(void (^)(void))block; 3. 队列的常见用法 -> 设置最大并发数
* get方法 - (NSInteger)maxConcurrentOperationCount;
* set方法 - (void)setMaxConcurrentOperationCount:(NSInteger)cnt ->队列其他操作 * 取消所有的操作
[queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复) * 暂停所有操作
[queue setSuspended:YES]; // 暂停队列中的所有任务 * 恢复所有操作
[queue setSuspended:NO]; // 恢复队列中的所有任务 4. 操作之间的依赖
// 设置依赖
// B依赖A , C依赖B
// 就是等操作A执行完毕后,才能执行B, B执行完后,才能执行C
[operationB addDependency:operationA];
[operationC addDependency:operationB]; 注: * 不能相互依赖
* 可以在不同的QUEUE的NSOperation之间创建依赖关系 5. 线程之间的通讯 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.执行耗时操作 // 2.回到主线程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 在这里执行在主线程的UI界面刷新操作
}];
}]; 6. 从其他线程回到主线程的方式
->perform
* performSelectorOnMainThread ->GCD
* dispatch_async(dispatch_get_main_queue(), ^{ }); ->NSOperationQueue
* [[NSOperationQueue mainQueue] addOperationWithBlock:^{ }]; */
NSOperation&NSOperationQueue是什么?
以GDC为底层,比GDC多了一些更简单实用的功能,并且更加面向对象的一套线程技术
怎么操作NSOperation?
和GDC一样, 也有队列和任务(操作)两个概念
通过操纵NSOperationQueue(队列),并且修改队列的某些属性,从而控制整个线程管理
创建队列的方式有两种 一是主队列,也就是主线程队列(同步串行队列) ,二是非主队列(默认异步并发队列)
【学习总结】【多线程】 多线程概要 & GDC & NSOperation的更多相关文章
- 孙鑫VC学习笔记:多线程编程
孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010 HQU Email:zgzhaobo@gmail.com QQ:452728574 Latest Modified ...
- 多线程开发之二 NSOperation
效果如下: ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UITableViewControll ...
- NDK学习笔记-JNI多线程
前面讲到记录到ffmpeg音视频解码的时候,采用的是在主线程中进行操作,这样是不行的,在学习了POSIX多线程操作以后,就可以实现其在子线程中解码了,也可以实现音视频同步了 简单示例 在native实 ...
- iOS开发之多线程(NSThread、NSOperation、GCD)
整理一些多线程相关的知识. 并行 & 并发 1.并行:并行是相对于多核而言的,几个任务同时执行.2.并发:并发是相对于单核而言的,几个任务之间快速切换运行,看起来像是"同时" ...
- Java:学习什么是多线程
线程是什么 进程是对CPU的抽象,而线程更细化了进程的运行流程 先看一下这个图 线程和进程的关系有 进程中就是线程在执行,所有(主)线程执行完了进程也就结束了 多个线程从1秒钟是同时运行完成,从1纳秒 ...
- Python 第四阶段 学习记录之----多线程
多线程 多线程例子, 注释部份即为多线程的使用 #-*- coding: utf-8 -*- # Wind clear raise # 2017/3/5 下午2:34 import socket im ...
- iOS开发多线程-多线程技术1
一.基本概念 1.什么是进程 进程就是指在系统中正在运行的一个应用程序 每个应用之间是相互独立的 每个进程都运行在其专有的并且受保护的内存空间内. 2.什么是线程 一个进程想要执行程序,就必须需要一个 ...
- java第五节 多线程/多线程的同步
/* 第五讲 多线程 了解进程和线程 在多任务系统中,每个独立执行的程序称为进程,也就是"正在进行的程序",我们现在使用的操作系统一般都是多任务的 即能够同时执行多个应用程序,实际 ...
- iOS之多线程开发NSThread、NSOperation、GCD
原文出处: 容芳志的博客 欢迎分享原创到伯乐头条 简介iOS有三种多线程编程的技术,分别是:(一)NSThread(二)Cocoa NSOperation(三)GCD(全称:Grand Centr ...
随机推荐
- Jersey(1.19.1) - Building URIs
A very important aspects of REST is hyperlinks, URIs, in representations that clients can use to tra ...
- Ehcache(2.9.x) - API Developer Guide, Using Explicit Locking
About Explicit Locking Ehcache contains an implementation which provides for explicit locking, using ...
- Android中用PULL解析XML
解析XML的方式有DOM,SAX,PULL,那为什么要在Android中使用PULL解析呢?首先来说一下PULL解析的优点,然后再说一下其他两种解析方式的缺点,答案就清晰可见啦. DOM不适合文档较大 ...
- sql常识-SQL 通配符
在搜索数据库中的数据时,您可以使用 SQL 通配符. SQL 通配符 在搜索数据库中的数据时,SQL 通配符可以替代一个或多个字符. SQL 通配符必须与 LIKE 运算符一起使用. 在 SQL 中, ...
- IIS日志
1.认识IIS日志 IIS日志默认存放在System32\LogFiles目录下,使用W3C扩展格式.下面我们通过一条日志记录来认识它的格式 2005-01-0316:44:57218.17.90.6 ...
- Sql Server Profiler跟踪死锁
Sql Server Profiler一个很重要的应用场景就是监视分析死锁. 下面通过一个例子来学习Profiler是如何监视死锁的. 1. 创建测试数据模拟死锁, 创建表Table_A和Table_ ...
- VS2012生成不依赖运行时不依赖MFC的MFC程序
转载请注明来源:http://www.cnblogs.com/xuesongshu/ 1.新建MFC或者Win32工程,全部使用默认设置 2.设置工程属性,展开配置属性,转到:常规~MFC的使用,修改 ...
- checkbox批量选中,获取选中的项的值
<!doctype html><html lang="en"> <head> <meta charset="UTF-8&quo ...
- 热键HotKeys
一:新建类HotKeys命名空间: using System.Runtime.InteropServices; 二:注册热键API [DllImport("user32")] pu ...
- SQL正常工作日上班安排
alter proc [work] as declare @i int begin id into #restdate from dt_work where work_date in (select ...