多线程

2016-08-31  本文已影响18人  紫云夕月

1.程序是一个可执行文件

2.进程是程序执行的一个操作实体

3.进程是线程的集合

4.多线程就是在一个程序(一个进程)中开启多条线路,为并发执行多个任务提供方便.

什么是线程?

1.进程当中并发执行的代码片段

2.线程是提高代码效率的一个手段

3.IOS中主要用于防止界面假死

4.线程是处理异步任务的主要手段

NSThread

优点:NSThread 比其他两个轻量级

缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销

1.+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

作用:开启并且执行一个线程

2.- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument

作用:创建一个线程但是不会执行,需要手动调用

3.NSThreadWillExitNotification

作用:通过通知中心监听此消息达到监听线程结束的目的

4.NSlock

作用:线程锁

5.如何取消NSThread

NSOperation

优点:不需要关心线程管理, 数据同步的事情,可以把精力放在自己需要执行的操作上。

1. NSOperation本身不是线程,它是一个线程操作

2.它常用的子类

1)NSInvocationOperation  通过方法指定线程要执行的任务

2)NSBlockOperation 通过block指定要执行的任务

3)可以继承NSOperation,然后重写main函数达到自定义任务的效果

3.NSOperationQueue 线程池,管理线程

可以设置最大开启的线程数 maxConcurrentOperationCount

如果设置为1,则成为串行队列,否则,为并发队列

GCD

GCD会自动根据任务在多核处理器上分配资源,优化程序。

1.什么是GCD

GCD 是苹果iOS4.0之后和block一起出现的技术,是苹果封装的更底层(c)更高效的多线程处理技术,GCD (grand-central-dispatch)是目前使用的最普遍的多线程处理技术,因为高效、简洁、实用

2.GCD的队列类型

1).主线程队列 dispatch_get_main_queue()

技术分享

2).子线程队列 dispatch_get_global_queue(0, 0)

技术分享

3.一次性执行(类似线程锁) static dispatch_once_t onceToken

Singleton为自定义的一个继承NSObject的类,时机应用中需要什么类型就写什么类型

技术分享

4.延时执行 dispatch_time_t ,dispatch_after

5.自定义队列dispatch_queue_create

技术分享

注意:自定义队列只开启一条线程,执行多个任务时为串行队列

6.分组合并dispatch_group_create

技术分享

7.dispatch_group_async

可以实现监听一组任务是否完成,完成后得到通知执行其他的操作

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^{

[NSThread sleepForTimeInterval:1];

NSLog(@"group1");

});

dispatch_group_async(group, queue, ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"group2");

});

dispatch_group_async(group, queue, ^{

[NSThread sleepForTimeInterval:3];

NSLog(@"group3");

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

NSLog(@"updateUi");

});

dispatch_release(group);

8.dispatch_barrier_async

是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"dispatch_async1");

});

dispatch_async(queue, ^{

[NSThread sleepForTimeInterval:4];

NSLog(@"dispatch_async2");

});

dispatch_barrier_async(queue, ^{

NSLog(@"dispatch_barrier_async");

[NSThread sleepForTimeInterval:4];

});

dispatch_async(queue, ^{

[NSThread sleepForTimeInterval:1];

NSLog(@"dispatch_async3");

});

9.dispatch_apply

执行某个代码片段N次。

dispatch_apply(5, globalQ, ^(size_t index) {

// 执行5次

});

四.线程间通信

线程间通信和进程间通信从本质上讲是相似的。线程间通信就是在进程内的两个执行流之间进行数据的传递,就像两条并行的河流之间挖出了一道单向流动长沟,使得一条河流中的水可以流入另一条河流,物质得到了传递。

1.performSelect On The Thread

框架为我们提供了强制在某个线程中执行方法的途径,如果两个非主线程的线程需要相互间通信,可以先将自己的当前线程对象注册到某个全局的对象中去, 这样相 互之间就可以获取对方的线程对象,然后就可以使用下面的方法进行线程间的通信了,由于主线程比较特殊,所以框架直接提供了在出线程执行的方法。

@interface NSObject (NSThreadPerformAdditions)

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUnti

2.Mach Port

在苹果的Thread Programming Guide的Run Pool一节的Configuring a Port-Based Input Source 这一段中就有使用Mach Port进行线程间通信的例子。 其实质就是父线程创建一个NSMachPort对象,在创建子线程的时候以参数的方式将其传递给子线程,这样子线程中就可以向这个传过来的 NSMachPort对象发送消息,如果想让父线程也可以向子线程发消息的话,那么子线程可以先向父线程发个特殊的消息,传过来的是自己创建的另一个 NSMachPort对象,这样父线程便持有了子线程创建的port对象了,可以向这个子线程的port对象发送消息了。

当然各自的port对象需要设置delegate以及schdule到自己所在线程的RunLoop中,这样来了消息之后,处理port消息的delegate方法会被调用,你就可以自己处理消息了。

上一篇下一篇

猜你喜欢

热点阅读