iOS多线程之NSThread
来源:互联网 发布:linux是什么意思啊 编辑:程序博客网 时间:2024/05/04 22:39
以前对多线程总是有点陌生感,虽然平时也一样在用,但总是感觉不够亲密。这两天就彻底整理一下,但是由于是demo代码那种,所以在这里我就不再重复敲字了,直接上代码吧。
//// JSC_NSThread.m// ios多线程学习//// Created by huasu on 17/2/28.// Copyright © 2017年 JY. All rights reserved.////NSThread实现的技术有下面三种:cocoa thread , POSIX threads ,Multiprocessing Services 一般使用的是cocoa thread 技术/* NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) –优点:NSThread 比其他两个轻量级,使用简单 –缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销 */#import "JSC_NSThread.h"@interface JSC_NSThread ()#define kURL @"http://s10.sinaimg.cn/mw690/56279263h7bdc5a0791f9&690.png"@property (nonatomic,weak)UIImageView *imageview;@property (nonatomic,strong)NSThread *thread;@end@implementation JSC_NSThread-(void)learn{ //NSThread有两种直接创建方式: //1> 类方法直接开启后台线程,并执行选择器方法 detachNewThreadSelector // 新建一个线程,调用@selector方法 [NSThread detachNewThreadSelector:@selector(bigDemo:) toTarget:self withObject:nil]; //2> 成员方法,在实例化线程对象之后,需要使用start执行选择器方法 initWithTarget // 成员方法 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(bigDemo:) object:nil]; // 启动start线程 [thread start]; // 参数: // selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。 // target :selector消息发送的对象 // argument:传输给target的唯一参数,也可以是nil,即object后面的参数 // 不显式创建线程的方法 // 用NSObject的类方法 performSelectorInBackground:withObject: 创建一个线程: //对于NSThread的简单使用,可以用NSObject的performSelectorInBackground替代 // performSelectorInBackground是将bigDemo的任务放在后台线程中执行 [self performSelectorInBackground:@selector(bigDemo) withObject:nil];}- (void)viewDidLoad { [super viewDidLoad]; UIImageView *imageview=[[UIImageView alloc]init]; self.imageview=imageview; imageview.frame=CGRectMake(10, 100, 200, 200); [self.view addSubview:imageview]; UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame=CGRectMake(50, 400, 220, 25); [button setTitle:@"加载图片" forState:UIControlStateNormal]; //添加方法 [button addTarget:self action:@selector(loadImageWithMultiThread) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; //如果网络不好,我们需要停止线程 UIButton *btn=[UIButton buttonWithType:UIButtonTypeRoundedRect]; btn.frame=CGRectMake(50, 500, 220, 25); [btn setTitle:@"停止加载" forState:UIControlStateNormal]; //停止线程 [btn addTarget:self action:@selector(stopLoadImage) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn];}-(void)stopLoadImage{ //判断线程是否完成,如果没有完成则设置为取消状态 //注意设置为取消状态仅仅是改变了线程状态而言,并不能终止线程 if (!self.thread.isFinished) { [self.thread cancel]; }}-(void)loadImageWithMultiThread{ //这样我们点击button时会创建一个子线程去执行任务,这样加载图片的时候我们主线程的ui就不会卡死 //如果多个线程加载图片,线程优先级范围为0~1,值越大优先级越高,每个线程的优先级默认为0.5 优先级越大的会越先执行,但未必第一个加载,首先代码中线程的启动顺序不一定,还有就是网络问题我们没法控制,每个线程执行时实际网络状况很可能不一致 NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL]; self.thread=thread; [thread start];}-(void)updateUI:(UIImage*) image{ self.imageview.image = image;}-(void)downloadImage:(NSString *) url{ NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]]; UIImage *image = [[UIImage alloc]initWithData:data]; if(image == nil){ }else{ [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES]; }}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
说到多线程了,肯定少不了的就是线程锁了,下面附一个经典的卖票例子吧
//// JSC_ticket.m// ios多线程学习//// Created by huasu on 17/3/1.// Copyright © 2017年 JY. All rights reserved.//#import "JSC_ticket.h"@interface JSC_ticket (){ int sum;//原始总票数 int tickets;//当前票数 int count;//售出票数 NSThread* ticketsThreadone; NSThread* ticketsThreadtwo; NSCondition* ticketsCondition;//线程锁 NSLock *theLock;//线程锁}@end@implementation JSC_ticket- (void)viewDidLoad { [super viewDidLoad]; //线程同步 [self text1];// //线程的顺序执行 他们都可以通过[ticketsCondition signal]; 发送信号的方式,在一个线程唤醒另外一个线程的等待。// [self text2];// 其他同步// 我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。// - (void)doSomeThing:(id)anObj// {// @synchronized(anObj)// {// // Everything between the braces is protected by the @synchronized directive.// } // }// 还有其他的一些锁对象,比如:循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,可以自己看官方文档学习}-(void)text1{ sum =100; tickets = 100; count = 0; theLock = [[NSLock alloc] init]; // 锁对象 ticketsCondition = [[NSCondition alloc] init]; ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run1) object:nil]; [ticketsThreadone setName:@"Thread-1"]; [ticketsThreadone start]; ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run1) object:nil]; [ticketsThreadtwo setName:@"Thread-2"]; [ticketsThreadtwo start];}-(void)text2{ sum =100; tickets = 100; count = 0; theLock = [[NSLock alloc] init]; // 锁对象 ticketsCondition = [[NSCondition alloc] init]; ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run2) object:nil]; [ticketsThreadone setName:@"Thread-1"]; [ticketsThreadone start]; ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run2) object:nil]; [ticketsThreadtwo setName:@"Thread-2"]; [ticketsThreadtwo start]; NSThread *ticketsThreadthree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil]; [ticketsThreadthree setName:@"Thread-3"]; [ticketsThreadthree start];}- (void)run1{ while (TRUE) { // 上锁 // [ticketsCondition lock]; [theLock lock]; if(tickets >= 0){ [NSThread sleepForTimeInterval:0.09]; count = sum - tickets; NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]); tickets--; }else{ break;//退出while死循环 } [theLock unlock]; // [ticketsCondition unlock]; } //如果没有线程同步的lock,卖票数可能是-1.加上lock之后线程同步保证了数据的正确性。 //上面例子我使用了两种锁,一种NSCondition ,一种是:NSLock。 NSCondition我已经注释了。}- (void)run2{ while (TRUE) { // 上锁 [ticketsCondition lock]; [ticketsCondition wait]; [theLock lock]; if(tickets >= 0){ [NSThread sleepForTimeInterval:0.09]; count = 100 - tickets; NSLog(@"当前票数是:%d,售出:%d,线程名:%@",tickets,count,[[NSThread currentThread] name]); tickets--; }else{ break; } [theLock unlock]; [ticketsCondition unlock]; }}-(void)run3{ while (YES) { [ticketsCondition lock]; [NSThread sleepForTimeInterval:3]; [ticketsCondition signal]; [ticketsCondition unlock]; }}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}/*#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller.}*/@end
1 0
- iOS多线程之NSThread
- ios多线程之NSThread
- iOS多线程之NSThread
- iOS多线程之NSThread
- iOS 多线程之NSThread
- IOS多线程之NSThread
- iOS --- 多线程之NSThread
- iOS多线程之NSThread
- iOS多线程之NSThread
- iOS多线程之NSThread
- iOS多线程之NSThread
- iOS-多线程之NSThread
- iOS多线程之NSThread
- IOS多线程开发之NSThread
- iOS多线程之Pthread/NSthread
- iOS多线程之Pthread/NSthread
- iOS多线程编程之NSThread
- iOS整理 -- 多线程之NSThread
- spark二次排序简单例子(JAVA)
- vuejs 双向绑定粗浅理解
- linux下搭建redis并解决无法连接redis的问题
- 项目中使用前端技术总结一(Sea.js)
- java 文件下载问题
- iOS多线程之NSThread
- ThreadPoolExecutor
- Java中==和equals的区别,equals和hashCode的区别
- at功能实现
- 线段树或树状数组求逆序数
- 【hdoj_2082】找单词
- reference and dereference of pointer
- tf.strided_slice 实例
- oralce的TIMESTAMP型字段作为关联条件