文档章节

多线程

west_zll
 west_zll
发布于 2016/04/26 15:47
字数 1448
阅读 5
收藏 0


多线程:有多少个任务需要同时执行,就至少需要多少线程。它是指应用程序中执行任务的载体。


1.使用系统方法直接隐式创建线程(如果使用InBackground优先级比较低,该线程不能管理)

    [self performSelectorInBackground:@selector(run:) withObject:@"隐式"];


2.使用NSThread创建线程(可以修改设置)

// 方式一:

    NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"测试线程"];

    // 设置名称

//    thread.name = @"测试线程";

    // 设置线程的优先级

    thread.threadPriority = NSOperationQueuePriorityHigh;

    // 开启线程

    [thread start];


// 方式二:(直接创建线程并执行,此线程也无法进行设置)

    [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"方式二"];


//在主线程中创建一个耗时操作,主线程即UI线程

-(void)run:(NSString *)str{

    // 得到当前线程

    NSThread * currentThread = [NSThread currentThread];

    for (int i = 0; i < 1000; i++) {

        NSLog(@"%d--%@--%@", i, str, currentThread);

        if (i == 500) {

            // 当前线程退出

//            [NSThread exit];

        }

    }

    [self performSelectorOnMainThread:@selector(setColor) withObject:nil waitUntilDone:YES];

}


各个线程间的关系:依赖关系和优先级的关系

互斥锁

// 如果出现多个线程同时争抢一个资源的时候,需要使用互斥锁来达到目的

// 要实现互斥锁,可以使用很多办法:synchronizedNSLockGCD的信号量,消费生产模式

互斥锁

@synchronized(self) {


}

NSOperation mainQueue

 // NSOperation 是一个创建多线程操作的类,但是不能够直接的使用,应该使用其子类:NSInvocationOperation NSBlockOperation,或者继承NSOperation自定义子类


// 如果直接使下面的两种方式,都是在主线程中执行任务

    operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"Invocation线程"];


//    使用block线程

operation2 = [NSBlockOperation blockOperationWithBlock:^{

        NSThread * thread = [NSThread currentThread];

        for (int i = 0; i < 100; i++) {

            NSLog(@"%d--%@--%@", i, @"block线程", thread);

        }

    }];


// 添加依赖关系,要求operation3必须依赖operation1,也是operation1执行完毕才执行operation3

    [operation3 addDependency:operation1];

    

    // 表示operation2执行完毕后才执行的代码

    [operation2 setCompletionBlock:^{

        NSLog(@"operation2执行完毕");

    }];


 // 得到一个封装operation的主队列, 并且把两个操作添加进入后会自动启动操作

  NSOperationQueue * queue = [NSOperationQueue mainQueue];

 // 创建一个新的队列,来执行异步操作

    NSOperationQueue * queue = [[NSOperationQueue alloc]init];

    [queue addOperation:operation1];

    [queue addOperation:operation2];

    [queue addOperation:operation3];

 // 取消所有的线程操作

    [queue cancelAllOperations];


  // 同时开启很多个线程执行(需要自己调整最优解)

    for (int i = 0; i < 10; i++) {

        [queue addOperationWithBlock:^{

            NSThread * thread = [NSThread currentThread];

            for (int i = 0; i < 1000; i++) {

                NSLog(@"%d--%@--%@", i, @"block", thread);

            }

        }];

    }

  GCD

// 以下代码只执行一次

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        NSLog(@"我只打印一次%@", [NSThread currentThread]);

    });


// 延时执行(默认是放到主线程执行,但是可以通过改变第三个参数来实现开启一个线程来执行)

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"延时打印%@", [NSThread currentThread]);

    });


// 创建队列的方法:

    // 方法一:得到主线程所在的队列

    dispatch_queue_t queue1 =  dispatch_get_main_queue();

    // 方法二:创建一个自定义的新的队列

    dispatch_queue_t queue2 = dispatch_queue_create("自定义串行队列", DISPATCH_QUEUE_SERIAL);

    

    dispatch_queue_t queue3 = dispatch_queue_create("自定义并行队列", DISPATCH_QUEUE_CONCURRENT);

    // 方法三:得到一个全局队列

    dispatch_queue_t queue4 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);


 // 使用GCD的方式处理事务,有以下两种办法:

    /************** 方法一:同步执行 (串行)******************/

    // 不能够使用同步操作的时候使用main线程所在的队列

//    dispatch_sync(queue1, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

    

    // 当同步操作使用自定义的串行队列的时候,相当于在主线程中执行,会卡UI

//    dispatch_sync(queue2, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

    

    // 当同步操作使用自定义的并行队列的时候,相当于在主线程中执行,会卡UI

//    dispatch_sync(queue3, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

    

    // 当同步操作使用全局队列的时候,相当于在主线程中执行,会卡UI

//    dispatch_sync(queue4, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });


    // 得出结论,同步请求都会卡UI,都是在主线程中执行,需要注意的是,使用同步不能够直接传入主线程所在的队列

    /************** 方法一:同步执行 (串行)end******************/


    

    /************** 方法二:异步执行 (并行)******************/

    

    // 当异步操作使用主线程所在的队列的时候,相当于在主线程中执行,会卡UI

//    dispatch_async(queue1, ^{

//        for (int i = 0; i < 10000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

    

    

    // 当异步操作使用自定义的串行队列的时候,会另外开启一个新的线程来执行所有的任务,不会卡UI,但是其他的所有的任务是一个一个执行的,这样的话并没有达到多线程的效率,当然也有可能有这样的业务需求

//    dispatch_async(queue2, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

//    

//    dispatch_async(queue2, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

    

    // 当异步操作使用自定义的并行队列的时候,会创建多个线程并行执行需求的任务

//    dispatch_async(queue3, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

//    

//    dispatch_async(queue3, ^{

//        for (int i = 0; i < 1000; i++) {

//            NSLog(@"%d--%@", i, [NSThread currentThread]);

//        }

//    });

    

    // 当异步操作使用全局队列的时候,会创建多个线程并行执行需求的任务

    dispatch_async(queue4, ^{

        for (int i = 0; i < 1000; i++) {

            NSLog(@"%d--%@", i, [NSThread currentThread]);

        }

    });

    

    dispatch_async(queue4, ^{

        for (int i = 0; i < 1000; i++) {

            NSLog(@"%d--%@", i, [NSThread currentThread]);

        }

    });


   /************** 方法二:异步执行 (并行)end******************/



  // 创建一个线程组

    dispatch_group_t group = dispatch_group_create();

    

    // 创建一个线程使用的队列

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    

    // 执行线程

    dispatch_group_async(group, queue, ^{

        for (int i = 0; i < 1000; i++) {

            NSLog(@"%d--%@", i, [NSThread currentThread]);

        }

    });

    

    dispatch_group_async(group, queue, ^{

        for (int i = 0; i < 1000; i++) {

            NSLog(@"%d--%@", i, [NSThread currentThread]);

        }

    });


    dispatch_group_async(group, queue, ^{

        for (int i = 0; i < 1000; i++) {

            NSLog(@"%d--%@", i, [NSThread currentThread]);

        }

    });


    dispatch_group_async(group, queue, ^{

        for (int i = 0; i < 1000; i++) {

            NSLog(@"%d--%@", i, [NSThread currentThread]);

        }

    });


    // 当此线程组里的所有的线程执行完毕之后执行

    dispatch_group_notify(group, queue, ^{

        NSLog(@"group里所有的线程执行完毕");

    });











© 著作权归作者所有

west_zll
粉丝 2
博文 78
码字总数 13506
作品 0
深圳
iOS工程师
私信 提问

暂无文章

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
13
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
10
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
12
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部