美文网首页
iOS四种多线程的基本使用

iOS四种多线程的基本使用

作者: 车在路上爬fly | 来源:发表于2019-02-25 17:51 被阅读0次

1.pthread 实现多线程操作(不常使用)

#pragma mark -- pThread
- (IBAction)pThreadClick:(UIButton *)sender {
    NSLog(@"主线程中进行。。。");
    pthread_t my_pthread;
    pthread_create(&my_pthread, NULL, run, NULL);
    
}
void *run(void *data){
    NSLog(@"这里是子线程。。。");
    for (int i = 0; i < 10; i++) {
        NSLog(@"%d",i);
        sleep(1);//模拟延时操作
    }
    return NULL;
}

2.NSThread实现多线程

#pragma mark -- nsThread
- (IBAction)nsThreadClick:(UIButton *)sender {
     NSLog(@"主线程中进行。。。");
    //创建方式1
    NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(nsThreadStart) object:nil];
    [thread1 setName:@"threadName_1"];
    [thread1 setThreadPriority:0.4];//优先级 0-1之间
    [thread1 start];
    
    NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(nsThreadStart) object:nil];
    [thread2 setName:@"threadName_2"];
    [thread2 setThreadPriority:0.6];
    [thread2 start];

    //创建方式2
//    [NSThread detachNewThreadSelector:@selector(nsThreadStart) toTarget:self withObject:nil];
    
    //创建方式3
//    [self performSelectorInBackground:@selector(nsThreadStart) withObject:nil];
    
}
-(void)nsThreadStart{
    NSLog(@"这里是子线程。。。的名字是%@",[NSThread currentThread].name);
    for (int i = 0; i < 10; i++) {
        NSLog(@"%d",i);
        sleep(1);
        if (i == 9) {
            //回到主线程刷新UI
            [self performSelectorOnMainThread:@selector(mainRefresh) withObject:nil waitUntilDone:YES];
        }
    }
}
-(void)mainRefresh{
    NSLog(@"回到主线程刷新UI");
}
. 线程中枷锁的方式:
        //方式一
        @synchronized (self) {
            //枷锁的代码
        }

        //方式二
        NSCondition *diction = [[NSCondition alloc]init];
        [diction lock];
        //枷锁的代码
        [diction unlock];

3.多线程之GCD讲解

//GCD的i基本使用
-(void)gcd1{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:3];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"回到主线程刷新UI");
        });
    });
}
//gcd多个任务的使用
-(void)gcd2{
    /*
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        NSLog(@"start task 1");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"end task 1");
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"start task 2");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"end task 2");
    });
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"start task 3");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"end task 3");
    });
    */
    
    //加到队列  按任务顺序执行(三个任务在同一个线程)------> 串行队列(dispatch_queue_create第二个参数传NULL)
//    dispatch_queue_t queue = dispatch_queue_create("com.lql.test.queue", NULL);
    
    //并行队列(dispatch_queue_create第二个参数传 DISPATCH_QUEUE_CONCURRENT)
    dispatch_queue_t queue = dispatch_queue_create("com.lql.test.queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"start task 1");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"end task 1");
    });
    dispatch_async(queue, ^{
        NSLog(@"start task 2");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"end task 2");
    });
    dispatch_async(queue, ^{
        NSLog(@"start task 3");
        [NSThread sleepForTimeInterval:1];
        NSLog(@"end task 3");
    });
    
}
模拟两个异步网络请求完成之后在执行别的任务:
/**
 业务: 模拟两个网络请求,当两个异步的网络请求 都成功之后,再去执行某一件事情
 */
-(void)gcd3{
    dispatch_queue_t queue = dispatch_queue_create("con.lql.te.queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_t group = dispatch_group_create();
    //模拟第一个接口开始请求
    dispatch_group_enter(group);
    [self sendRequest1:^{
        NSLog(@"第一个网络请求成功");
        dispatch_group_leave(group);
    }];
     //模拟第二个接口开始请求
    dispatch_group_enter(group);
    [self sendRequest12:^{
        NSLog(@"第一个网络请求成功");
        dispatch_group_leave(group);
    }];

    //所有任务处理完成的统一回调
    dispatch_group_notify(group, queue, ^{
        NSLog(@"All task Done");
        //回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"回到主线程刷新UI");
        });
    });
}
//模拟第一个 异步网络请求
-(void)sendRequest1:(void(^)(void))block{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"start task 1");
        [NSThread sleepForTimeInterval:2];
        NSLog(@"end task 1");
        dispatch_async(dispatch_get_main_queue(), ^{
            if (block) {
                block();
            }
        });
    });
}

//模拟第二个 异步网络请求
-(void)sendRequest12:(void(^)(void))block{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"start task 2");
        [NSThread sleepForTimeInterval:2];
        NSLog(@"end task 2");
        dispatch_async(dispatch_get_main_queue(), ^{
            if (block) {
                block();
            }
        });
    });
}

GCD的其他使用
-(void)gcd4{
    //gcd单利的使用
    TestSingle *shared = [TestSingle instance];
    NSLog(@"%@",shared);//地址不变
    
    //gcd的延时使用
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"2s之后执行");
    });
}

4.多线程之NSOperation讲解

使用NSOperation的两种方式:
  • 1.NSInvocationOperation & NSBlockOperation
  • 2.自定义类继承NSOperation WeChat061bbe38eeb7a53aa5a0bc0d6e32727b.png
- (IBAction)nsoperationClick:(UIButton *)sender {
    //方式1
//    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
    //方式2
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"block %d",i);
            [NSThread sleepForTimeInterval:2];
        }
    }];
    
    if (!self.operationQueue) {
        self.operationQueue = [[NSOperationQueue alloc]init];
    }
//    [operation start];//主线程执行
    [self.operationQueue addOperation:operation];
    NSLog(@"end");
}
-(void)test{
    for (int i = 0; i < 3; i++) {
        NSLog(@"invocation %d",i);
        [NSThread sleepForTimeInterval:2];
    }
}

自定义NSOperation

1.自定义MyOperation类

#import "MyOperation.h"
@interface MyOperation()
@property(nonatomic,copy)NSString *operName;
@property BOOL isOver;
@end
@implementation MyOperation
-(instancetype)initWithName:(NSString *)name{
    if (self = [super init]) {
        self.operName = name;
    }
    return  self;
}
-(void)main{
    //模拟网络请求
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:2];
        if (self.cancelled) {
            return ;
        }
        NSLog(@"%@,继续执行操作",self.operName);
        self.isOver = YES;
    });
    
    while (!self.isOver && !self.cancelled) {
        [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
    
}
@end

2.使用

- (IBAction)nsoperationClick:(UIButton *)sender {
    //方式1
//    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
    //方式2
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 3; i++) {
            NSLog(@"block %d",i);
            [NSThread sleepForTimeInterval:2];
        }
    }];
    
    if (!self.operationQueue) {
        self.operationQueue = [[NSOperationQueue alloc]init];
    }
    
    [self.operationQueue setMaxConcurrentOperationCount:2];//设置线程个数
    
////    [operation start];//主线程执行
    [self.operationQueue addOperation:operation];

    MyOperation *myopertionA = [[MyOperation alloc]initWithName:@"myopA"];
    MyOperation *myopertionB = [[MyOperation alloc]initWithName:@"myopB"];
    MyOperation *myopertionC = [[MyOperation alloc]initWithName:@"myopC"];
    MyOperation *myopertionD = [[MyOperation alloc]initWithName:@"myopD"];
    
    //添加依赖  B->C->A->D
    [myopertionD addDependency:myopertionA];//D依赖A
    [myopertionA addDependency:myopertionC];//A依赖C
    [myopertionC addDependency:myopertionB];//C依赖B
    
    [self.operationQueue addOperation:myopertionA];
    [self.operationQueue addOperation:myopertionB];
    [self.operationQueue addOperation:myopertionC];
    [self.operationQueue addOperation:myopertionD];
     NSLog(@"end");
}
-(void)test{
    for (int i = 0; i < 3; i++) {
        NSLog(@"invocation %d",i);
        [NSThread sleepForTimeInterval:2];
    }
}

相关文章

网友评论

      本文标题:iOS四种多线程的基本使用

      本文链接:https://www.haomeiwen.com/subject/tqveyqtx.html