GCD(1)

#import "ViewController.h"

int threadNumber = 0;

int newThingNumber = 0;

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}


//1如果主线程和子线程是并行的,倚靠CPU的调度,主线程和子线程都有机会得到执行。
//2如果要在子线程里面改变主线程里面的数据,就在里面的最后 一个参数使用传地调用(void *)&c,否则使用传值调用(void *)c
//3使用pthread_join的目的在于:怕主线程执行的过快,子线程还没有执行,主线程就执行完毕并且退出了。


- (IBAction)doSomething:(id)sender {
 
    
//    如果是在单线程里执行,则按纽状态的执行中字样会一直持续10秒
//    目前,对于iOS来说, 程序的GUI,是在主线程里执行的。换句话:所有UI程序都应该在主线程里运行
//    默认情况, button的回调方法, 是在主线程运行着
    
  
    
//      [self doThing:nil];
 
//    开启新的线程,意思是同步执行(同步)
//    第一种办法来开启一个新的线程
//    第一个参数:开启后台线程, 需要执行的代码(任务), 第二个参数是线程通信参数
    
//     [self performSelectorInBackground:@selector(doThing:) withObject:@"Hellowangdelong"];

  

    
    //    第二种开启线程的方法
//    启动一个子线程,并使用doThing:作为线程的入口点(线程任务)
//    第二个参数:指定是哪个对象定义了线程的入口点(线程作务),
//    第三个参数:传递给子线程的数据(实现线程这间通信的手段)
     
//     [NSThread detachNewThreadSelector:@selector(doThing:) toTarget:self withObject:@"Hello"];
    


    
    //    第三种开启线程的方法
    
     //    创建一个线程对象, 可以实现对线程何时开始运行的控制。
//     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(doThing:) object:@"qingYun"];
     //    给线程起一个名字, 用来标识这个线程。
//     thread.name = @"FirstQingYunThread";
    
     //    启动线程
//     [thread start];
    
    
 
    
    //    第四种开启线程的方法
    
     //    创建一个队列
//     NSOperationQueue *queque = [[NSOperationQueue alloc] init];
     //    创建子任务, 定义子任务必须是NSOperation的子类
//     NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doThing:) object:@"HelloOperationQueue"];
     //    当把任务添加到队列后, 自动开启线程,
//     [queque addOperation:operation];
     //    在同一个NSOperationQueue队列不同出现同一个任务对象,否则会出现异常
//         [queque addOperation:operation];
    
       
    
    
    //  第五种开启线程的方法
    
//     NSOperationQueue *queque = [[NSOperationQueue alloc] init];
//     NSBlockOperation *oper = [NSBlockOperation blockOperationWithBlock:^{
//     NSLog(@"do thing...");
//     threadNumber++;
//     //    表示当前执行doThing的线程对象
//     NSThread *currentThread = [NSThread currentThread];
//     
//     //    isMainThread:如果是主线程的话, 则返回YES,否则NO
//     if ([currentThread isMainThread]) {
//     NSLog(@"Main thread...%d",threadNumber);
//     }else
//     {
//     NSLog(@"Peer thread...%d",threadNumber);
//     }
//     
//     [NSThread sleepForTimeInterval:10];//让处理器休眠10秒
//     NSLog(@"finish doThing");
//     
//     }];
//     
//     [queque addOperation:oper];
//
    
    
    
    
    //    第六种开启线程的方法
    //    GCD
    //    Serial 队列  (NULL, nil Nil NSNull)的区别是什么?第一个参数是唯一标识创建的队列对象的
#if 0
    dispatch_queue_t queue = dispatch_queue_create("wangdelong", NULL);
//    异步执行GCD的block(线程任务)
//    1、对于serial队列来说,主线程可以理解为一个queue, queue 与queue之间肯定异步执行,
//    2、对于同一个serial队列时的子任务,同步执行,遵循FIFO

    dispatch_async(queue, ^{
        
        NSLog(@"doThing...");
        
        threadNumber++;
        
        //     表示当前执行doThing的线程对象
        NSThread *currentThread = [NSThread currentThread];
        
        //如果是在主线程里执行的话, 打印出在主线程。
        //    否则,则打印是对等线程
        //    判断是主线程还是对等线程(异步)
        if ([currentThread isMainThread]) {
            NSLog(@"Main thread is :%d",threadNumber);
            
        }else{
            
            NSLog(@"Peer thread id :%d",threadNumber);
        }
        
        //    //让处理器休眠10秒
        [NSThread sleepForTimeInterval:5];
        
        NSLog(@"finish working");

    });
    
    
//    dispatch_queue_t secondqueue = dispatch_queue_create("wangdelong", NULL);
    
    dispatch_async(queue, ^{
        
        NSLog(@" doThing...");
        
        threadNumber++;
        
        //     表示当前执行doThing的线程对象
        NSThread *currentThread = [NSThread currentThread];
        
        //如果是在主线程里执行的话, 打印出在主线程。
        //    否则,则打印是对等线程
        //    判断是主线程还是对等线程(异步)
        if ([currentThread isMainThread]) {
            NSLog(@"secondMain thread is :%d",threadNumber);
            
        }else{
            
            NSLog(@"secondPeer thread id :%d",threadNumber);
        }
        
        //    //让处理器休眠10秒
        [NSThread sleepForTimeInterval:5];
        
        NSLog(@"second finish working");
        
    });
#endif
    
//      Concurrent 队列 同一个队列里的多个子任务之间也是并发执行的(注意这是与serial队列的区别)
//    同一个队列的不同子任务并发执行
//    不同的队列,他的调度顺序是根据优先级来确定, 优先级高的, 先调度。
//    第一个参数:用于标识队列的优先级,有如下几种:
//    #define DISPATCH_QUEUE_PRIORITY_HIGH
//    #define DISPATCH_QUEUE_PRIORITY_DEFAULT
//    #define DISPATCH_QUEUE_PRIORITY_LOW
//    #define DISPATCH_QUEUE_PRIORITY_BACKGROUND
//    第二个参数:写0就可以, 目前保留

    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_queue_t secondqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    
    
    
    dispatch_async(queue, ^{
        NSLog(@"first doThing...");
        
        threadNumber++;
        
        //     表示当前执行doThing的线程对象
        NSThread *currentThread = [NSThread currentThread];
        
        //如果是在主线程里执行的话, 打印出在主线程。
        //    否则,则打印是对等线程
        //    判断是主线程还是对等线程(异步)
        if ([currentThread isMainThread]) {
            NSLog(@"first Main thread is :%d",threadNumber);
            
        }else{
            
            NSLog(@"first Peer thread id :%d",threadNumber);
        }
        
        //    //让处理器休眠10秒
        [NSThread sleepForTimeInterval:5];
        
        NSLog(@"first finish working");

    });
    
    
    
    dispatch_sync(secondqueue, ^{
        NSLog(@"second doThing...");
        
        threadNumber++;
        
        //     表示当前执行doThing的线程对象
        NSThread *currentThread = [NSThread currentThread];
        
        //如果是在主线程里执行的话, 打印出在主线程。
        //    否则,则打印是对等线程
        //    判断是主线程还是对等线程(异步)
        if ([currentThread isMainThread]) {
            NSLog(@"second Main thread is :%d",threadNumber);
            
        }else{
            
            NSLog(@"second Peer thread id :%d",threadNumber);
        }
        
        //    //让处理器休眠10秒
        [NSThread sleepForTimeInterval:5];
        
        NSLog(@"second finish working");
        
    });


    //    表示当前执行doThing的线程对象
    NSThread *currentThread = [NSThread currentThread];
    
    //    isMainThread:如果是主线程的话, 则返回YES,否则NO
    if ([currentThread isMainThread]) {
        NSLog(@"This is Main thread...%d",threadNumber);
    }else
    {
        NSLog(@"This is Peer thread...%d",threadNumber);
    }

    
}


-(void)doThing:(id)object
{
    
    NSLog(@"doThing...:%@",object);
    
    threadNumber++;

//     表示当前执行doThing的线程对象
    NSThread *currentThread = [NSThread currentThread];
    
//如果是在主线程里执行的话, 打印出在主线程。
//    否则,则打印是对等线程
//    判断是主线程还是对等线程(异步)
    if ([currentThread isMainThread]) {
        NSLog(@"Main thread is :%d",threadNumber);
        
    }else{
        
        NSLog(@"Peer thread id :%d",threadNumber);
    }
    
//    //让处理器休眠10秒
    [NSThread sleepForTimeInterval:10];
    
    NSLog(@"finish working");
    
}

//重新定义一个button,
- (IBAction)doNewThing:(id)sender {
    
    
    NSLog(@"do another thing...:%d",newThingNumber);
    
    newThingNumber++;
    if ([NSThread isMainThread]) {
        NSLog(@"do another thing is main thread");
    }else
    {
        NSLog(@"do another thing is peer thread");
    }
    
    [NSThread sleepForTimeInterval:3];
    NSLog(@"do another thing finished");
}

@end

原文地址:https://www.cnblogs.com/wangdelong/p/3852815.html