首页 > 代码库 > 同步与异步

同步与异步

          为简化多线程应用的开发,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状态。

  

同步与异步