多线程知识点(二)

1:互斥锁,只有一个线程进行(例如:读写)操作

2.栈区上面的对象随时可能销毁,ARC下block会自动保存到堆区

  //NSGlobalBlock全局区(未使用局部变量)

//    void (^task)() = ^{

//        NSLog(@"task");

//    };

//    NSLog(@"%@",task);

//   

//    int a = 6;

//    //NSStackBlock  栈区上面的对象随时可能会被销毁

//    void (^task2)() = ^{

//        NSLog(@"%d",a);

//    };

//    NSLog(@"task2 %@",task2);

//    //NSMallocBlock 堆区

//    void (^task3)() = ^{

//        NSLog(@"%d",a);

//    };

//    NSLog(@"task3 %@",[task3 copy]);

3.为对象添加一个block的属性,为他通过set方法进行赋值,然后就可以通过对象的属性来对定义好的block进行调用

 [self setMyBlock:^{

        NSLog(@"%d",a);

}];

4.单例可以通过互斥锁,也可以通过1次执行,但是单例的效率高5.同步串行:不开启新的线程,按顺序执行

6.异步串行:开启1条新的线程,按顺序执行

7.同步并行:不开启新的线程,按顺序执行

8.异步并行:开启新的线程,多线程执行

9.同步(不具备开启新线程的能力)异步是任务的区别,串行(顺序执行)并行是队列的区别

10.主队列是在主线程空闲的时候进行,主队列同步会造成死锁

(解决死锁,将主队列放到一条子线程里面执行)

11. 创建串行队列

dispatch_queue_t serialQueue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);

12.创建并行队列

dispatch_queue_t concurrentQueue = dispatch_queue_create("itcast", DISPATCH_QUEUE_CONCURRENT

dispatch_sync(concurrentQueue, task1)

13.全局队列,是系统提供好的异步队列

14.同步任务,开启一条子线程,在子线程里面进行同步任务

例如:dispatch_async(dispatch_get_global_queue(0, 0), ^{

        //验证密码

        dispatch_sync(dispatch_get_global_queue(0, 0), ^{

           

            [NSThread sleepForTimeInterval:1.0];

            NSLog(@"验证密码 %@",[NSThread currentThread]);

        });

        //扣费

        dispatch_sync(dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:1.0];

            NSLog(@"扣费 %@",[NSThread currentThread]);

        });

        //下载应用

        dispatch_sync(dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:1.0];

            NSLog(@"下载应用 %@",[NSThread currentThread]);

        });

 

    });

15.GCD的单独的地方:一次执行,调度组,延迟执行

延迟执行

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

      NSLog(@"hello");

 });

采用一次执行制造单例

+(instancetype)sharadNetworkToolsOnce

{

    static NetworkTools *tools;

   

    //依次性执行,线程安全

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        if (tools == nil) {

            tools = [NetworkTools new];

        }

    });

   

    return tools;

}

调度组的使用

//调度组

    dispatch_group_t group = dispatch_group_create();

   

    //调度组的使用

    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"下载第一首歌曲 %@",[NSThread currentThread]);

    });

    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

        [NSThread sleepForTimeInterval:1.0];

         NSLog(@"下载第二首歌曲 %@",[NSThread currentThread]);

    });

    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

        NSLog(@"下载第三首歌曲 %@",[NSThread currentThread]);

    });

   

    //如果调度组里面的任务执行完毕之后,会调用dispatch_group_notify函数

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"下载完成 %@",[NSThread currentThread]);

    });

调度组的原理

dispatch_group_t group = dispatch_group_create();

   

    dispatch_group_enter(group);

    //模拟下载歌曲1

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"下载第一首歌曲 %@",[NSThread currentThread]);

        dispatch_group_leave(group);

    });

   

    dispatch_group_enter(group);

    //模拟下载歌曲2

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"下载第2首歌曲 %@",[NSThread currentThread]);

        dispatch_group_leave(group);

    });

   

    dispatch_group_enter(group);

    //模拟下载歌曲3

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"下载第3首歌曲 %@",[NSThread currentThread]);

        dispatch_group_leave(group);

    });

   

    //如果调度组里面的任务执行完毕之后,会调用dispatch_group_notify函数

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"下载完成 %@",[NSThread currentThread]);

    });

16. NSOperation子类

    NSInvocationOperation;

   NSBlockOperation;

17.

   参数1:调用的方法所属的类(不一定是self,只要实现方法即可)

   参数2:要调用的方法

   参数3:给要调用的方法传递的参数

    //操作

    NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(demo) object:nil];

    //调用start不会开启新的线程 [op start];

    //队列

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

   

    //把操作添加到队列

[queue addOperation:op];

18.创建全局的队列

 -(NSOperationQueue *)queue

{

    if (_queue == nil) {

        _queue = [[NSOperationQueue alloc]init];

    }

    return _queue;

}

使用全局队列

  [self.queue addOperationWithBlock:^{

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

}];

19.记住 [op start] 不会开启新的线程,只有加入队列才会开启新的线程

原文地址:https://www.cnblogs.com/chaoyueME/p/5574823.html