首页 > 代码库 > 同步与异步
同步与异步
为简化多线程应用的开发,IOS提供了GCD来实现多线程。它的核心就是队列与任务,任务在队列中始终以FIFO的顺序来处理。但由于任务的执行时间不同,因此先处理的任务不一定先结束。
使用GCD实现多线程只需遵守两个步骤即可:1.创建队列2.将任务提交给队列。队列分为串行队列与并行队列。当我们向队列中提交任务时就涉及到两种方式:异步提交任务(dispatch_async)、同步提交任务(dispatch_sync)。
一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。
进程同步:就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。进程异步:当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。 如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别。
先看异步提交任务。创建一个单视图应用,向storyboard布局文件中添加一个按钮,button类型为自定义,为default、highlighted两种状态设置不同的titil及字体颜色。并未该button绑定concurrent方法(向并发队列异步提交任务)
#import "FKViewController.h" @interface FKViewController () @end @implementation FKViewController // 定义2个队列 dispatch_queue_t serialQueue; dispatch_queue_t concurrentQueue; - (void)viewDidLoad { [super viewDidLoad]; // 创建串行队列 serialQueue = dispatch_queue_create("fkjava.queue", DISPATCH_QUEUE_SERIAL); // 创建并发队列 concurrentQueue = dispatch_queue_create("fkjava.queue" , DISPATCH_QUEUE_CONCURRENT); } - (IBAction)concurrent:(id)sender { // 依次将2个代码块提交给并发队列 // 两个代码块可以并发执行 dispatch_async(concurrentQueue, ^(void) { for (int i = 0 ; i < 100; i ++) { NSLog(@"%@=====%d" , [NSThread currentThread] , i); } }); dispatch_async(concurrentQueue, ^(void) { for (int i = 0 ; i < 100; i ++) { NSLog(@"%@------%d" , [NSThread currentThread] , i); } }); } @end
运行程序后,我们会看到。两个block块中的代码是交替执行的,它们是并发的。button的在点击的同时迅速切换为高亮状态后又恢复为default状态。
再看同步提交任务。创建一个单视图应用,向storyboard布局文件中添加一个按钮,button类型为自定义,为default、highlighted两种状态设置不同的titil及字体颜色。并未该button绑定click方法(向全局并发队列同步提交任务)
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)clicked:(id)sender { // 以同步方式先后提交2个代码块 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) , ^(void){ for (int i = 0 ; i < 100; i ++) { NSLog(@"%@=====%d" , [NSThread currentThread] , i); [NSThread sleepForTimeInterval:0.1]; } }); // 必须等第一次提交的代码块执行完成后,dispatch_sync()函数才会返回, // 程序才会执行到这里,才能提交第二个代码块。 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) , ^(void){ for (int i = 0 ; i < 100; i ++) { NSLog(@"%@-----%d" , [NSThread currentThread] , i); [NSThread sleepForTimeInterval:0.1]; } }); } @end点击button程序运行,dispatch_sync函数先后两次提交代码块。从运行结果中看到,第一次提交代码块完成后才会执行第2次提交。整个过程中按钮一直处于高亮状态,知道第二个代码块执行完后,clicked方法才能返回,button回复到default状态。
同步与异步