多线程涉及的概念##
进程###
*进程是指在系统中正在运行的一个应用程序
*每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内
线程###
*一个进程要想执行任务,必须得有线程(一个进程至少要有1条线程:主线程)
*线程是进程的基本执行单元,一个进程的所有任务呢都在线程中执行
线程的串行#####
*一个线程中任务的执行是串行的
*如果要在一个线程中执行多个任务,那么只能一个一个的按顺序执行这些任务
*在同一时间内,一个线程只能执行一个任务
多线程###
-
一个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务
原理: 1. 同一时间,CPU只能处理1条线程,只有1条线程在执行 2. 多线程并行(同时)执行,其实就是CPU快速地在多条线程之间调度(切换) 3. 如果CPU调度线程的时间足够快,就造成了多线程并行执行的假象 多线程的优缺点: 优点: 1.能适当提高程序的执行效率 2.能适当提高资源利用率(CPU、内存利用率) 缺点: 1.开启线程需要占用一定的内存空间,如果开启大量的线程,会占用大量的内存空间,减低程序的性能 2.线程越多,CPU在调度线程上的开销就越大 3.程序设计更加复杂:比如线程之间的通信、多线程的数据共享
iOS中的主线程###
-
一个iOS程序运行后,默认会开启1条线程,称为主线程或UI线程
主线程的主要作用: 1.显示刷新UI界面 2.处理UI事件 主线程的使用注意: 1.不要将比较耗时的操作放到主线程中 2.耗时操作会卡住主线程,严重影响UI的流畅度。
iOS中多线程的实现方案###
pthread:
使用C语言,适用于UnixLinuxWindows等系统、跨平台可移植、使用难度大。线程的生命周期由程序员管理
NSThread:
使用OC语言,使用更加面向对象,简单易用,可直接操作线程对象。线程的生命周期由程序员管理
GCD(Grand Central Dispatch):
使用C语言,旨在替代NSThread等线程技术,充分利用设备的多核,线程的生命周期由系统自动管理
NSOperation:
使用OC语言,基于GCD,使用更加面向对象,线程的生命周期由系统自动管理
多线程实现方案详解##
NSThread详解###
首先查看Apple官方文档,了解其属性与内部方法:
#import <Foundation/NSObject.h>
#import <Foundation/NSDate.h>
@class NSArray<ObjectType>, NSMutableDictionary, NSDate, NSNumber, NSString;
NS_ASSUME_NONNULL_BEGIN
@interface NSThread : NSObject {
@private
id _private;
uint8_t _bytes[44];
}
+ (NSThread *)currentThread;//获取当前线程
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject: (nullable id)argument;//创建一个新的线程并自动启动
+ (BOOL)isMultiThreaded;//判断是否为多线程
@property (readonly, retain) NSMutableDictionary *threadDictionary;
+ (void)sleepUntilDate:(NSDate *)date;//暂停线程,一直到指定的时间,这段时间处于阻塞状态
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;//暂停线程,时间长度为ti秒,这段时间处于阻塞状态
+ (void)exit;//终止线程
+ (double)threadPriority;//这个类方法获取当前正在执行的线程的优先级
+ (BOOL)setThreadPriority:(double)p;//这个类方法用于设置当前正在执行的线程的优先级
@property double threadPriority NS_AVAILABLE(10_6, 4_0); // To be deprecated; use qualityOfService below
@property NSQualityOfService qualityOfService NS_AVAILABLE(10_10, 8_0); // read- only after the thread is started
+ (NSArray<NSNumber *> *)callStackReturnAddresses NS_AVAILABLE(10_5, 2_0);
+ (NSArray<NSString *> *)callStackSymbols NS_AVAILABLE(10_6, 4_0);
@property (nullable, copy) NSString *name NS_AVAILABLE(10_5, 2_0);
@property NSUInteger stackSize NS_AVAILABLE(10_5, 2_0);
@property (readonly) BOOL isMainThread NS_AVAILABLE(10_5, 2_0);
+ (BOOL)isMainThread NS_AVAILABLE(10_5, 2_0); // 判断当前线程是否为主线程 + (NSThread *)mainThread NS_AVAILABLE(10_5, 2_0);//获取主线程
- (instancetype)init NS_AVAILABLE(10_5, 2_0) NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_AVAILABLE(10_5, 2_0);//创建线程对象。 方法对象、方法、参数
@property (readonly, getter=isExecuting) BOOL executing NS_AVAILABLE(10_5, 2_0);
@property (readonly, getter=isFinished) BOOL finished NS_AVAILABLE(10_5, 2_0);
@property (readonly, getter=isCancelled) BOOL cancelled NS_AVAILABLE(10_5, 2_0);
- (void)cancel NS_AVAILABLE(10_5, 2_0);
- (void)start NS_AVAILABLE(10_5, 2_0);
- (void)main NS_AVAILABLE(10_5, 2_0); // thread body method
@end
FOUNDATION_EXPORT NSString * const NSWillBecomeMultiThreadedNotification;
FOUNDATION_EXPORT NSString * const NSDidBecomeSingleThreadedNotification;
FOUNDATION_EXPORT NSString * const NSThreadWillExitNotification;
@interface NSObject (NSThreadPerformAdditions)
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
// 该方法的作用是在主线程中,执行制定的方法(代码块)来修改页面UI的状态 aselector就是,要定义我们要执行的方法。withObject:arg定义了,我们执行方法 时,传入的参数对象。类型是id。(我们可以传入任何参数)waitUntilDone:YES指定,当前线程是否要被阻塞,直到主线程将我们制定的代码块执行完。
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject: (nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject: (nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
//调用指定线程中的方法
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);//创建线程并执行
@end
NS_ASSUME_NONNULL_END