IOS多线程学习二:NSThread

文章目录

  • 一.NSThread 线程创建方式
  • 二.线程状态
    • 线程休眠
    • 线程强制退出
  • 三.线程安全隐患
    • @synchronized
  • 四.线程通信

一.NSThread 线程创建方式

selector后为线程调用的方法,object后为传入线程方法的参数类

NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@“abc”];
需要调[thread start];

//从主线程中分离一个子线程去执行任务,无需手动开启,分离出来后会立即启动

[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@“miss”];

//开一个后台线程,无需手动启动

[self performSelectorInBackground:@selector(run:) withObject:@“back”];

//把耗时操作放在子线程的方法中执行,防止界面卡顿

-(void)run:(id)obj{}

获取当前线程[NSThread currentThread];
获取主线程[NSThread mainThread];

二.线程状态

1.新建线程,alloc,开辟一段内存空间放置线程对象
2.开启线程,start,线程对象会被放置到对应的线程池中。就绪状态,等待CPU调度。
3.当CPU调度该线程时,运行状态。
4.当CPU调度其他线程的时候,返回就绪状态。
5.当调用了sleep/等待同步锁,进入阻塞状态(blocked),线程对象从线程池中移出来;当sleep到时/等到了同步锁,线程进入就绪状态,线程对象回归到线程池中,等待CPU调度。
6.线程的死亡,线程任务执行完成,自动死亡;线程异常/强制退出。
一旦线程死亡,线程对象从内存中移除,不能再重新开启,如果尝试重新开启线程,程序会挂掉。

线程休眠

第一种方法

[NSThread sleepForTimeInterval:2];

第二种方法

[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];

如果想线程任务执行一部分之后永远不要开启

[NSThread sleepUntilDate:[NSDate distantFuture]];//在遥远的未来

线程强制退出

[NSThread exit] ;

三.线程安全隐患

一块资源可能会被多个线程共享,即多个线程同时访问操作同一个数据(对象,变量,文件)(线程并发执行),很容易引发数据错乱和数据安全问题。
解决方案:使用线程同步技术(按先后顺序执行),常用技术是加锁。

@synchronized

互斥锁的优点:有效防止因多线程抢夺资源造成的数据安全问题。
缺点:因为线程等待,需要消耗大量的CPU资源。
注意:互斥锁又叫线程同步。
线程同步:多条线程在同一条线上执行,按顺序执行任务。
@synchronized(self) 创建一个互斥锁,保证此时没有其他线程对self对象进行修改
@synchronized(锁对象){//需要锁定的代码}
锁对象是同一个,是唯一的。

IOS多线程学习二:NSThread_第1张图片

四.线程通信

在一个进程中,线程往往不是孤立存在的,多个线程之间是存在有通信关系的。
体现:
1.一个线程传递数据给另一个线程
2.一个线程执行完成任务后转到另外一个线程继续执行任务。
eg:在子线程中做耗时操作加载网络图片,然后回到主线程显示网络图片。
self.imageView.image=[UIImage imageNamed: name];添加的图片是在工程内部的图片。
从网络下载的图片用self.imageView.image=[UIImage imageWithData: data];

NSURL *url=[NSURL URLWithString:IMAGE_URL];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *image=[UIImage imageWithData:data];

注意:xcode7以后如果想要使用http协议,需要在Info.plist里面添加字段. App Transport Security settings / Allow Arbitrary Loads YES
//查看代码的执行时间
NSDate *begin=[NSDate date];
代码
NSDate *end=[NSDate date];
NSLog(@"%f",[end timeIntervalSinceDate:begin]);

由子线程回归到主线程:
在子线程的方法里调:

[self performSelectorOnMainThread:@selector(loadImage:) withObject:image waitUntilDone:YES];

[self performSelector:@selector(loadImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];

[self.imageView performSelector:@selector(setImage:)onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];

说明:waitUntilDone:YES,等@selector里的方法执行完后,才执行之后的代码,
waitUntilDone:NO, @selector里的方法和之后的代码是并发执行的。
IOS多线程学习二:NSThread_第2张图片

你可能感兴趣的:(IOS,NSThread)