iOS中的三种多线程

iOS提供了三种多线程的技术:NSThreadGCD

NSOperation和NSOperationQueue

 

1.使用NSThread创建多线程:

创建NSThread线程有实力方法和类方法两种方法

- (void)viewDidLoad {
   
    //创建NSThread线程有实例方法和类方法两种方法
    //实例方法创建线程对象
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(show) object:nil];
    [thread start];
    
    //通过类方法创建线程
    [NSThread detachNewThreadSelector:@selector(show) toTarget:self withObject:nil];
}

-(void)show
{
    NSLog(@"%@",[NSThread currentThread]);
}

调用实例方法创建线程返回一个thread对象,因此必须还要调用一下start方法启动线程,而调用类方法可以直接创建并启动线程。无论类方法还是实力方法本质上都是通过观察者模式,调用target对象的selector方法,作为线程的执行体,执行结果如下:

2016-04-25 10:56:36.842 ios三种多线程[1767:96781] <NSThread: 0x7f9bb260db80>{number = 3, name = (null)}

2016-04-25 10:56:36.842 ios三种多线程[1767:96780] <NSThread: 0x7f9bb27162f0>{number = 2, name = (null)}

可以看到程序产生了number分别为2和3的新线程,这是因为number为1的是主线程。在NSlog语句中,currentThread方法是查看当前线程对象。

线程进入睡眠状态时,不会获得执行的机会:

//让线程进入睡眠状态
    [NSThread sleepForTimeInterval:0.5];

线程的优先级:

线程的优先级在0.0~1.0之间,优先级高获会的更多的执行机会,线程默认优先级为0.5

//设置线程的优先级为最高
    thread.threadPriority = 1.0;<span style="font-size:18px;"><strong>
</strong></span>

使用@synchronized实现线程同步:

@synchronized(self)  //括号内为同步监视器,表示同步代码运行前必须先获得同步监视器的锁定
    {
        
        //需要同步的代码块
        
    }//释放同步锁,为了保证线程访问安全,在任何线程修改指定资源时都要对该资源进行锁定,锁定期间其它线程不得修改。<span style="font-size:18px;">
</span>

使用NSLock实现线程同步:

使用NSLock相当于同步监视器为NSLock对象,每次只有一个线程能对NSLock加锁

NSLock *lock ;
    [lock lock];
    //需要同步的代码
    
    [lock unlock];


2.使用GCD实现多线程:
相对于要手动管理线程同步安全的NSThread方法,GCD则要简单得多;

GCD的一大优势就是充分利用CPU的内核,让双核、四核的CPU更高效的工作;

GCD的核心是队列,使用GCD来实现多线程只需要创建队列,并把任务放在队列中处理。GCD的队列类型如下:

(1)主队列:dispatch_get_main_queue()

所有添加到主队列的任务都是在主线程中执行的;

(2)全局队列: dispatch_get_global_queue()

全局队列也叫并发队列,所有添加到全局队列中的任务都是并发执行,可能会开启多个线程;

(3)串行队列:dispatch_queue_create()

串行队列中所有的任务都按顺序执行,只开一条线程;


除了队列,GCD中还有同步与异步两种提交任务的方式,同步还是异步取决于方法名,与是什么样的队列没有关系

同步:dispatch_sync    在当前线程执行任务不会开启新的线程

异步:dispatch_async   在当前线程执行任务会开启新的线程

使用GCD下载网络图片的例子

//使用GCD下载网络图片:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //通过异步的全局队列下载图片
        NSString *url = @"http://img5.imgtn.bdimg.com/it/u=1179777510,2740895801&fm=21&gp=0.jpg";
        NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
        UIImage *image = [[UIImage alloc] initWithData:data];
        
        //下载图片完成后在主线程中更新UI界面
        if(image != nil)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                _imageView.image = image;
            });
        }
        else
        {
            NSLog(@"图片下载失败");
        }
    
    });

用GCD实现执行完线程p1,p2后在执行p3线程:

把p1,p2放到dispatch group中,再和p3用串行队列;

3.使用NSOperation与NSOperationQueue实现多线程:

NSOperation和NSOperationQueue相对于GCD来说更加的面向对象,同时它可以控制最多线程的数量,并且可以控制线程执行的顺序。使用步骤同样是先创建NSOperation,然后把NSOperation添加到NSOperationQueue中。

NSOperation中通过maxConcurrentOperationCount来控制最多的子线程数量,通过addDependence控制线程先后执行的顺序;

使用NSOperation下载网络图片的例子

//使用NSOperation下载网络图片
    NSOperationQueue *_queue = [[NSOperationQueue alloc] init];
    //设置线程的最大数量为2
    _queue.maxConcurrentOperationCount = 2;
    NSString *url = @"http://img5.imgtn.bdimg.com/it/u=1179777510,2740895801&fm=21&gp=0.jpg";
    
    NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
        UIImage *image = [[UIImage alloc] initWithData:data];
        if (image != nil) {
            //在主线程中执行更新UI的方法
            [self performSelectorOnMainThread:@selector(updateUI) withObject:image waitUntilDone:YES];
        }
    }];
    
    NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"执行线程op2");
    }];
    
    //将NSOperation添加到NSOperationQueue中
    [_queue addOperation:op1];
    [_queue addOperation:op2];
    
    //op1执行完毕之后才能执行op2
    [op2 addDependency:op1];




 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值