美文网首页
多线程和runloop

多线程和runloop

作者: BlueSky520 | 来源:发表于2017-11-02 16:47 被阅读0次

    //
    // RunLoopTest.m

    import "RunLoopTest.h"

    import <pthread.h>

    import <CoreFoundation/CFRunLoop.h>

    @interface RunLoopTest() {
    NSRunLoop * loop;
    }
    @end
    @implementation RunLoopTest

    • (instancetype)init {
      if (self = [super init]) {
      // [self createThread];
      // NSLog(@"并行加同步");
      // [self DispatchQueueConcurrentAndSync];
      // [self DispatchQueueConcurrentAndAsync];

    // NSLog(@"串行加同步");
    // [self DispatchQueueSerialAndSync];
    // [self mainQueueAndAsync];
    // [self dispatchConnect];
    // [self dispatchBarrierAsync];
    [self dispatchGroup];
    }
    return self;

    }

    • (void)createThread {
      // 1.Pthreads
      // pthread_t thread;
      // pthread_create(&thread, NULL, start, NULL);
      // 2.NSThread
      // NSThread * thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(thread1Run) object:nil];
      // [thread1 start];
      // 3.GCD
      dispatch_queue_t queue1 = dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);//串行队列
      dispatch_queue_t queue2 = dispatch_queue_create("test2.queue", DISPATCH_QUEUE_CONCURRENT);//并行队列
      dispatch_sync(queue1, ^{
      // NSLog(@"同步执行");
      });//不会开辟新的线程

      dispatch_async(queue1, ^{
      // NSLog(@"异步执行");
      });//会开辟新的线程
      }

    pragma mark -- 并行队列 + 同步执行

    • (void)DispatchQueueConcurrentAndSync {
      dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//采用全局并行队列
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      });
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"3------%@",[NSThread currentThread]);
      }
      });
      //可以预测到三个线程会按编码的顺序依次执行,并且都是在主线程上执行
      NSLog(@"syncConcurrent---end");
      }

    pragma mark -- 并行队列 + 异步执行

    • (void)DispatchQueueConcurrentAndAsync {
      dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//采用全局并行队列
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      });
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"3------%@",[NSThread currentThread]);
      }
      });
      //可以预测到先打印的是@"asyncConcurrent---end",因为这个方法是在主线程上执行,等级高于异步开的子线程,然后打印3个子线程,并且三个子线程打印的顺序是不固定,因为是并行队。所以异步线程并不影响主线程
      NSLog(@"asyncConcurrent---end");
      }

    pragma mark -- 串行队列 + 异步执行

    • (void)DispatchQueueSerialAndAsync {
      // 会开启新线程,但是因为任务是串行的,执行完一个任务,再执行下一个任务
      dispatch_queue_t queue1 = dispatch_queue_create("test1.queue1", DISPATCH_QUEUE_SERIAL);
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      });
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"3------%@",[NSThread currentThread]);
      }
      });
      //可以预测到先打印的是@"asyncConcurrent---end",因为这个方法是在主线程上执行,等级高于异步开的子线程,然后打印按顺序依次执行3个子线程里面的方法,并且三个子线程打印顺序是固定,因为是串行队列。所以异步线程并不影响主线程
      NSLog(@"asyncSerial---end");
      }

    pragma mark -- 串行队列 + 同步执行

    • (void)DispatchQueueSerialAndSync {
      // 不会开启新线程,执行完一个任务,再执行下一个任务
      dispatch_queue_t queue1 = dispatch_queue_create("test1.queue1", DISPATCH_QUEUE_SERIAL);
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      });
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"3------%@",[NSThread currentThread]);
      }
      });
      NSLog(@"syncSerial---end");
      //可以预测到三个线程会按编码的顺序依次执行,并且都是在主线程上执行

    }

    pragma mark -- 主队列 + 同步执行

    • (void)mainQueueAndSync {
      NSLog(@"syncMain---begin");

      // 互等卡住不可行(在主线程中调用)
      dispatch_queue_t queue1 = dispatch_get_main_queue();
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      });
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      dispatch_sync(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"3------%@",[NSThread currentThread]);
      }
      });
      NSLog(@"syncMain---end");
      //可以预测到三个线程会按编码的顺序依次执行,并且都是在主线程上执行

    }

    pragma mark -- 主队列 + 异步执行

    • (void)mainQueueAndAsync {
      NSLog(@"asyncMain---begin");

      dispatch_queue_t queue1 = dispatch_get_main_queue();
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      });
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      dispatch_async(queue1, ^{
      for (int i = 0; i < 2; ++i) {
      NSLog(@"3------%@",[NSThread currentThread]);
      }
      });
      NSLog(@"asyncMain---end");

    }

    pragma mark -- GCD线程之间的通讯

    • (void)dispatchConnect {

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      for (int i = 0; i < 2; i ++) {
      NSLog(@"1------%@",[NSThread currentThread]);
      }
      dispatch_async(dispatch_get_main_queue(), ^{
      for (int i = 0; i < 2; i ++) {
      NSLog(@"2------%@",[NSThread currentThread]);
      }
      });
      });

    // 先进行子线程的操作,然后回到主线程进行下一步操作
    }

    pragma mark -- GCD的栅栏方法 dispatch_barrier_async

    • (void)dispatchBarrierAsync {
      dispatch_queue_t queue = dispatch_queue_create("12323", DISPATCH_QUEUE_CONCURRENT);
      dispatch_async(queue, ^{
      NSLog(@"1------%@",[NSThread currentThread]);
      });
      dispatch_async(queue, ^{
      NSLog(@"2------%@",[NSThread currentThread]);
      });

      dispatch_barrier_async(queue, ^{
      NSLog(@"等一会在进行后面的答应---%@",[NSThread currentThread]);
      });
      dispatch_async(queue, ^{
      NSLog(@"3------%@",[NSThread currentThread]);
      });
      dispatch_async(queue, ^{
      NSLog(@"4------%@",[NSThread currentThread]);
      });

    }

    pragma mark -- GCD的队列组 dispatch_group

    • (void)dispatchGroup {
      dispatch_group_t group1 = dispatch_group_create();
      dispatch_group_async(group1, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      //耗时操作1
      NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
      loop = [NSRunLoop currentRunLoop];
      [loop addTimer:timer forMode:NSRunLoopCommonModes];
      [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //主线程等待,但让出主线程时间片,然后过10秒后返回

      });
      dispatch_group_async(group1, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      //耗时操作2
      NSTimer * timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
      loop = [NSRunLoop currentRunLoop];
      [loop addTimer:timer1 forMode:NSRunLoopCommonModes];
      [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]]; //主线程等待,但让出主线程时间片,然后过10秒后返回

      });
      // 等上面的耗时操作都完成了,再回到主线程

      dispatch_group_notify(group1, dispatch_get_main_queue(), ^{
      NSLog(@"3");
      });
      }

    • (void)timerAction {
      NSLog(@"%@",[NSThread currentThread]);
      }

    • (void)thread1Run {

    }
    //static CFSpinlock_t loopsLcok;
    @end

    相关文章

      网友评论

          本文标题:多线程和runloop

          本文链接:https://www.haomeiwen.com/subject/ercapxtx.html