zoukankan      html  css  js  c++  java
  • 多线程

    程序:就是代码⽣成的可执⾏的应⽤。    
    进程:跑起来的程序。      
    线程:程序中独⽴运⾏的代码段。(block就是)。      
    ⼀个进程是由多个线程(⼀个以上)组成的。进程申请资源和分配资源给线程⽤,线程⽤到资源。   
     
    每个进程都包含⾄少⼀个线程,即主线程。主线程在程序跑动的时候被创建,⽤于执⾏main函数⾥的东西。 
     
    主线程负责的是,所有代码的执⾏,包括UI更新,⽹络请求,本地存储等等。
    主线程的代码都是顺序执⾏,不能并⾏执⾏。 
     
    ⽤户可以开辟许多新的线程,这些线程都是主线程的⼦线程。 
    注意的是,主线程和⼦线程都是相互独⽴执⾏代码的,互不影响,并发执⾏。 
     
    注意:UI更新,必须放在主线程中去更新。因为开辟的⼦线程,是不受控制的,什么时候执⾏完毕我们⽆法控制。再⼦线程更新UI出现的bug⽆法预料。
    NSThread是相对于后⾯两个NSOperationQueue、GCD来说,是⼀个轻量级的多线程。
     
    //
    //  ViewController.m
    //  多线程
    //
    //  Created by cqy on 16/2/16.
    //  Copyright © 2016年 程清杨. All rights reserved.
    //

    #import "ViewController.h"

    @interface ViewController ()
    {
        NSThread *_thread;
        int i ;
    }
    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        NSThread *newThead = [NSThread currentThread];//获取当前线程
        NSThread *mainThead = [NSThread mainThread];//获取主线程
        [newThead setName:@"线程名"];
        if ([newThead isMainThread]) {
            NSLog(@"currentThread = %@",mainThead);
        }
       
       
        //第一种创建NSThread(第⼀种创建⽅式:需要⼿动启动[thread start];也要⼿动结束[thread cancel];⼦线程。)
       //第⼀个参数:随来执⾏
       // 第⼆个参数:去执⾏什么⽅法?这个⽅法⾥⼀般是⼦线程要完成的⼀些事:(⺴络请求,或者其他)。
       // 第三个参数:去执⾏的那个⽅法,顺便带⼀个参数过去。
       
       // NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadAction:) object:nil];
        //手动开启线程
        //[thread start];
        //结束线程
        //[thread cancel];
        // //第⼆种创建⽅式:不需要⼿动去开启⼦线程。参数意义与第⼀种⼀样。
       // [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
        //隐式创建线程
        //[self performSelectorInBackground:@selector(threadAction:) withObject:self];
        // 在主线程上执行
        [self performSelectorOnMainThread:@selector(Open) withObject:self waitUntilDone:YES];
        // Do any additional setup after loading the view, typically from a nib.
    }
    -(void)Open{
        NSLog(@"open...");
        //新创建一个子线程
        [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"qwe"];
       
       
    }
    -(void)threadAction:(NSThread *)sender{
         NSLog(@"threadAction...");
        NSTimer *timer=[NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(timeSchedule) userInfo:nil repeats:YES];
       
        NSRunLoop *runLoop=[NSRunLoop currentRunLoop];
       
        [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
        while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
      
    }
    -(void)timeSchedule{
         NSLog(@"timeSchedule...");
      
        NSLog(@"now is %d",i++);
        //在指定线程上执行操作
        _thread = [[NSThread alloc]initWithTarget:self selector:@selector(WillClose) object:nil];
        //暂停当前线程几秒
        [NSThread sleepForTimeInterval:3];
        [_thread start];
       }
    -(void)WillClose{
      
            NSLog(@"will close...");
       
        [self performSelector:@selector(Close) onThread:_thread withObject:nil waitUntilDone:YES];
        }
    -(void)Close{
        NSLog(@"close............");
        //停止当前线程
        [NSThread exit];

    }

    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }

    /*
    注意:
    再多线程⽅法中,需要添加⾃动释放池。
    应⽤程序再启动时,系统⾃动为主线程创建了⾃动释放池。我们⼿动添加的⼦
    线程,需要添加⾃动释放池。
     */
    @end
     
    NSOperation  
    NSOperation  
    mvc中属于M层,⽤来封装单个任务的相关代码的⼀个抽象类。这个抽象类不能直接使⽤,⽽是⽤它的⼦类来执⾏实际任务。    
    NSOperation只是⼀个操作,本⾝并没有主线程、⼦线程之分,可以使⽤再任意线程中。通常与NSOperationQueue⼀起使⽤。
    //
    //  ViewController.m
    //  多线程02-NSOperation
    //
    //  Created by cqy on 16/2/16.
    //  Copyright © 2016年 程清杨. All rights reserved.
    //

    #import "ViewController.h"

    @interface ViewController ()

    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        NSInvocationOperation *inOp = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationAction:) object:nil];
        [inOp start];
        //封装了要执⾏的代码块。要执⾏的代码都放在block⾥执⾏了。
        NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"block操作0:%@",[NSThread currentThread]);
           
            }];
        //在NSBlockOperation对象中添加一个操作,如果NSBlockOperation对象包含了多个操作,有一个是在主线程中执行,其他均在子线程中
        [blockOp addExecutionBlock:^{
            NSLog(@"block操作1:%@",[NSThread currentThread]);
        }];
        [blockOp addExecutionBlock:^{
            NSLog(@"block操作2:%@",[NSThread currentThread]);
        }];
       
        [blockOp start];
      
        //注意:添加操作之前要放在start之前
        //创建队列:将操作放入队列中(主队列除外),默认在子线程中执行,且不需要手动start
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        NSInvocationOperation *Operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2) object:nil];
        [queue addOperation:Operation];
        [queue addOperationWithBlock:^{
            NSLog(@"block操作队列3:%@",[NSThread currentThread]);
        }];
       
        // Do any additional setup after loading the view, typically from a nib.
    }
    -(void)run2{
        NSLog(@"队列执行操作4:%@",[NSThread currentThread]);
    }
    -(void)operationAction:(NSInvocationOperation *)sender{
        NSLog(@"operationAction....");
    }
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    @end
     
    GCD
     
    GCD是苹果公司封装好的⼀个系统,⽤来应对多核处理系统。gcd⼤部分代码都是函数的多线程,性能⾼,功能强⼤。      
    GCD以队列的⽅式进⾏⼯作,先进先出(o),GCD根据分发队列的的类型,创建适量线程,完成⼯作。     
    cgd分为三种队列:     
    主队列,全局队列,⾃定义队列。 
    1、串⾏队列:前⼀个任务完成,才能执⾏下⼀个任务(包括主队列和⾃定义队列)   
    2、并⾏队列:各个任务独⽴执⾏,互不⼲扰,也是先进先出(包括了全局队列和⾃定义队列)。 
     
    //
    //  ViewController.m
    //  多线程03-GCD
    //
    //  Created by cqy on 16/2/16.
    //  Copyright © 2016年 程清杨. All rights reserved.
    //

    #import "ViewController.h"

    @interface ViewController ()

    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self oneMain];
        [self twoMain];
        [self threeMain];
        [self fourMain];
       
        // Do any additional setup after loading the view, typically from a nib.
    }
    -(void)oneMain{
        // 主队列(串)
        //dispatch_queue_t是⼀个类型,mainQueue是类型的实例名。
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        //dispatch_get_main_queue(),获取主队列
        // 添加任务(三种队列都⽤这个⽅法添加)
        dispatch_async(mainQueue, ^{
            //dispatch_async(mainQueue,^(block)),这个⽅法是吧任务添加到mainQueue主队列中。block块⾥是要执⾏的任务。
            NSLog(@"第1个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(mainQueue, ^{
            NSLog(@"第2个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(mainQueue, ^{
            NSLog(@"第3个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(mainQueue, ^{
            NSLog(@"第4个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(mainQueue, ^{
            NSLog(@"第5个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(mainQueue, ^{
             NSLog(@"第6个任务,当前线程:%@",[NSThread currentThread]);
        });
        //解释:1、dispatch_queue_create 是创建⾃定义队列的⽅式。第⼀个参数是队列标⽰符,第⼆个参数是告诉系统,这个队列是串⾏的。2、dispatch_async,添加任务到myQueue1这个⾃定义队列中。block块中是执⾏的任务。
    }
    -(void)twoMain{
        // ⾃定义队列(串)
        // 第⼆个参数,告诉是串⾏的。
        dispatch_queue_t myQueue = dispatch_queue_create("myQ1",   DISPATCH_QUEUE_SERIAL);
        dispatch_async(myQueue, ^{
            NSLog(@"第01个任务,当前线程:%@",[NSThread  currentThread]);
        });
        dispatch_async(myQueue, ^{
            NSLog(@"第02个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(myQueue, ^{
            NSLog(@"第03个任务,当前线程:%@",[NSThread currentThread]);
        });
        dispatch_async(myQueue, ^{
            NSLog(@"第04个任务,当前线程:%@",[NSThread currentThread]);
        });
       
    }
    -(void)threeMain{
        // 全局(并⾏)
        dispatch_queue_t globelQ =
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                  0);
        dispatch_async(globelQ, ^{
            NSLog(@"第-1个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(globelQ, ^{
            NSLog(@"第-2个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(globelQ, ^{
            NSLog(@"第-3个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(globelQ, ^{
            NSLog(@"第-5个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(globelQ, ^{
            NSLog(@"第-6个任务,当前线程为:%@",[NSThread currentThread]);
        });
        // 解释dispatch_get_global_queue创建⼀个全局队列。DISPATCH_QUEUE_PRIORITY_DEFAULT:队列的优先级,default是系统默认。
       
       
       
    }
    -(void)fourMain{
        // ⾃定义(并⾏)
        dispatch_queue_t myQueue2 = dispatch_queue_create("Q2",          DISPATCH_QUEUE_CONCURRENT);
       
        dispatch_async(myQueue2, ^{
            NSLog(@"第1-个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(myQueue2, ^{
            NSLog(@"第2-个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(myQueue2, ^{
            NSLog(@"第3-个任务,当前线程为:%@",[NSThread currentThread]);
        });
        dispatch_async(myQueue2, ^{
            NSLog(@"第4-个任务,当前线程为:%@",[NSThread currentThread]);
        });
        //解释:dispatch_queue_create 创建⾃定义队列。第⼀个参数是队列标⽰符,第⼆个参数:DISPATCH_QUEUE_CONCURRENT是告诉系统,创建的是并⾏的队列。

    }
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    @end
     
     
     
     
     
  • 相关阅读:
    [ACM训练] 数据结构----树、二叉树----c++ && python
    [机器学习] ——KNN K-最邻近算法
    [Python学习] Linux环境下的Python配置,必备库的安装配置
    [Python学习] python 科学计算库NumPy—矩阵运算
    [Python学习] python 科学计算库NumPy—tile函数
    [机器学习] ——初识及实践选择
    [机器学习] 虚拟机VMware中使用Ubuntu的联网问题
    使用ScribeFire,Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结
    工作常用 随笔记录
    JavaScript取子串方法slice,substr,substring对比表
  • 原文地址:https://www.cnblogs.com/iQingYang/p/5194713.html
Copyright © 2011-2022 走看看