并排:两个线程,两个任务(连个执行者)

并行:两个线程,两个任务,一个执行者


1.进程与线程的区别

线程是CPU运行和独立调度的基本单位,进程是资源分配的基本单位,线程只拥有一小部分的资源,一个程序至少包含一个进程,一个进程至少包含一个线程,一个进程中的多个线程共享当前进程所拥有的资源。

一个应用程序只能有一个主线程,主线程:对UI的操作,代码只能顺序执行,只有一个主线程

子线程:多用来处理繁重的数据操作任务


2.多线程开发

  优点:

(1)使用线程可以把程序中占据时间长的任务放到后台去处理,如图片,视频的下载

(2)发挥多核处理器的优势,并发执行让系统运行的更快,更流畅,使用户体验更好

  缺点:

 (1)大量的线程降低代码的可读性

 (2)更多的线程需要更多的内存空间

 (3)当多个线程对同一资源出现争夺的时候,要注意线程安全的问题

  

   

//获得当前的线程
    NSThread *currentThread = [NSThread currentThread];
   //获取主线程
   NSThread *mainThread = [NSThread mainThread];
   //让当前线程休眠5秒
   [NSThread sleepForTimeInterval:5];
   [NSThreadsleepUntilDate:(NSDate *)]
    

    //实现多线程的第一种方法
    [self performSelectorInBackground:@selector() withObject:nil]

   NSObject 自带的多线程的处理方法

   优点:写法简单

   缺点:不能处理线程安全问题


 

//实现多线程的第二种方法
     //NSThread(两种创建方式)
     [NSThread *thread = [NSThread alloc]initWithTarget: self          selector:@selector(textThread)];
     //线程名:
     thread.name = @"mickey";
    //让线程开始执行任务
    [thread start ]
   [thread release]

    优点:提供一系列方法获取线程,操作线程

    缺点:默认没处理线程安全问题,而且对线程的设置非常繁琐

    NSThread  的一个对象,就代表一个线程


//NSThread 线程的第二种创建方式
    [NSThread detachNewThreadSelector:@selector(textThread)       toTarget:self withObject:nil];

//
  NSOperationQueue 操作队列实现多线程处理
  //串行队列:
   //并行队列:同时执行多个任务,最大并发数(线程池线程数)就是最多几个线程
 //队列 管理线程的最基本的方法
     NSOperation 这个类的一个对象,代表一个任务
    (写一个类继承NSOperation 
      在MyOperation.m文件中。
- (void)main
{
    //要执行的任务都在main方法中写
    // 1.获取当前的线程
NSThread *currentThread = [NSThreadcurrentThread];
NSLog(@"当前线程:%@", currentThread);
     
int a = 0;
for (int i =0; i < 600000000; i++) {
        a++;
    }
NSLog(@"a:%d", a);
}
     )
      MyOperation *op = [[MyOperation alloc]init];
      //一个任务直接执行,会在当前的线程执行,不会自己开辟子线程
       [po start]
       [po release]

       
    //  系统提供的两个NSOperation子类
    //    NSInvocationOperation *invocationOp = [     [NSInvocationOperation alloc] initWithTarget:self selector:@selector(textThread) object:nil];
     
 //    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{}];

     

的使用

    //优点:能够非常合理的安排线程的重用,对线程安全也做了非常好的处理,使用也非常简单

    // 缺点:效率略低

   

NSOperationQueue *queue = [[NSOperationQueuealloc] init];
     
    //  设置最大并发数
    [queue setMaxConcurrentOperationCount:2];
     
    MyOperation *op1 = [[MyOperationalloc]init];
    MyOperation *op2 = [[MyOperationalloc] init];
    MyOperation *op3 = [[MyOperationalloc] init];
    MyOperation *op4 = [[MyOperationalloc] init];
    //向队列中添加任务
addOperation:op1];
addOperation:op2];
addOperation:op3];
addOperation:op4];
   
      //多线程处理的第三中方法
     GCD Grand Central Dispatch 中央调度
     GCD是基于C语言 和Block语法的一个多线程解决方案(C语言效率比较高)
      
    //创建一个队列
     //参数1:队列名 (C语言写法)
     //参数2:队列类型 (串行、并行)
      DISPATC_QUEUE_SERIAL 串行
      DISPATCH_QUEUE_CONCURRENT concurrent//并行


串行

      

//    //  在队列中安排任务
//    // 参数1:给哪个队列安排任务
参数2:要执行的任务
 //    dispatch_async(myQueue, ^{
 //        [self textThread];
 //    });


    // 1个主队列(串行) 4个全局队列--》本身就有不同的优先级(并行)都是单例 靠函数获取
    //主队列 串行队列,是系统刷新UI和处理UI操作的地方

    

获取主队列

//    dispatch_async(mainQueue, ^{
 //        [self textThread];
 //    });

    // 获取全局队列

    //参数1:选择的是哪个优先级的全局队列

    //参数2:暂时没用,只能填0

//    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 //    dispatch_async(globalQueue, ^{
 //        [self textThread];
 //    });
 



 #warning GCD
     
     
    //同步加载图片卡界面
    // @"http://img2.duitang.com/uploads/item/201207/23/20120723003157_nKcvY.thumb.600_0.jpeg";
    //  子线程 同步请求  数据
    //  主线程 刷新UI/赋值
     
    //  主队列
    dispatch_queue_t mainQueue =dispatch_get_main_queue();
    //  子队列
    dispatch_queue_t globalQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
     
dispatch_async(globalQueue, ^{
         
        NSString *str =@"http://img2.duitang.com/uploads/item/201207/23/20120723003157_nKcvY.thumb.600_0.jpeg";
        str = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURLURLWithString:str];
        //  获取NSData的同步方法
NSData *data = [NSDatadataWithContentsOfURL:url];
        //  将NSData对象转为UIImage对象
UIImage *image = [UIImageimageWithData:data];
         
        //  要进行的UI视图操作     回到主线程
dispatch_async(mainQueue, ^{
             
self.imageView.image
        });
         
    });
     
     
     
    //在单例方法中应用
    //在保证线程安全的情况下,让代码只执行一次
static dispatch_once_t
dispatch_once(&onceToken, ^{
        NSLog(@"gao yuanyuan");
    });
     
    //在延迟xx秒后执行一段代码
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
NSLog(@"hahaha");
    });