美文网首页
多线程进阶

多线程进阶

作者: 一代骄马 | 来源:发表于2018-09-15 15:21 被阅读14次

1.线程死锁问题

1)

dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"1111");

    });

结果:会死锁,崩溃

原因:sync同步队列会阻塞当前线程(主线程),直到block里的任务完成。而执行任务的主线程已经被阻塞,不能在执行任务,所以就会死锁。

2)

  dispatch_queue_t queue =  dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    dispatch_sync(queue, ^{

        dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"1111");

        });

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

        NSLog(@"222");

    });

结果:会阻塞当前线程,但是不会死锁崩溃;

原因:阻塞的是异步线程,执行任务的是主线程

3)

  dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    dispatch_async(queue, ^{

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

        dispatch_sync(queue, ^{

          NSLog(@"3-----%@",[NSThreadcurrentThread]);

        });

    });

结果:会造成死锁崩溃。

原因:sync会阻塞当前的线程,即

4)????????

 dispatch_queue_tqueue =  dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    dispatch_async(queue, ^{

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

        dispatch_queue_tqueue1 =  dispatch_queue_create("test",DISPATCH_QUEUE_SERIAL);

        dispatch_sync(queue1, ^{

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

        });

        dispatch_sync(queue1, ^{

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

        });

    });

2.线程锁及其性能

来源:iOS中保证线程安全的几种方式与性能对比 - 简书

iOS的线程安全与锁 - CocoaChina_让移动开发更简单

不再安全的 OSSpinLock | Garan no dou

深入理解 iOS 开发中的锁

@synchronized、NSLock、dispatch_semaphore、NSCondition、pthread_mutex、OSSpinLock

性能对比:

OSSpinLock: 46.15 ms

dispatch_semaphore:          56.50 ms

pthread_mutex:                    178.28 ms

NSCondition:                          193.38 ms

NSLock:                                  175.02 ms

pthread_mutex(recursive):  172.56 ms

NSRecursiveLock:                  157.44 ms

NSConditionLock:                  490.04 ms

@synchronized:                      371.17 ms

1)OSSpinLock

自旋锁的实现原理比较简单,就是死循环。当a线程获得锁以后,b线程想要获取锁就需要等待a线程释放锁。在没有获得锁的期间,b线程会一直处于忙等的状态。如果a线程在临界区的执行时间过长,则b线程会消耗大量的cpu时间,不太划算。所以,自旋锁用在临界区执行时间比较短的环境性能会很高。

主要原因发生在低优先级线程拿到锁时,高优先级线程进入忙等(busy-wait)状态,消耗大量 CPU 时间,从而导致低优先级线程拿不到 CPU 时间,也就无法完成任务并释放锁。这种问题被称为优先级反转。

2)dispatch_semaphore

dispatch_semaphore实现的原理和自旋锁有点不一样。首先会先将信号量减一,并判断是否大于等于0,如果是,则返回0,并继续执行后续代码,否则,使线程进入睡眠状态,让出cpu时间。直到信号量大于0或者超时,则线程会被重新唤醒执行后续操作。

dispatch_semaphore_t lock = dispatch_semaphore_create(1);    //创建信号量

 dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);  //降低信号量  等于0时需要等待

//需要执行的代码

dispatch_semaphore_signal(lock);    //提升信号量

3)pthread_mutex

互斥锁的实现原理与信号量非常相似,不是使用忙等,而是阻塞线程并睡眠,需要进行上下文切换。

4)NSLock

NSLock 只是在内部封装了一个 pthread_mutex,属性为 PTHREAD_MUTEX_ERRORCHECK,它会损失一定性能换来错误提示。

5)@synchronized

这其实是一个 OC 层面的锁, 主要是通过牺牲性能换来语法上的简洁与可读。

我们知道 @synchronized 后面需要紧跟一个 OC 对象,它实际上是把这个对象当做锁来使用。这是通过一个哈希表来实现的,OC 在底层使用了一个互斥锁的数组(你可以理解为锁池),通过对对象去哈希值来得到对应的互斥锁。

相关文章

  • Swift多线程:GCD进阶,单例、信号量、任务组

    Swift多线程:GCD进阶,单例、信号量、任务组 Swift多线程:GCD进阶,单例、信号量、任务组

  • GeekBand - iOS 多线程和RunLoop 总结

    iOS 开发高级进阶 第三周 多线程 Runloop iOS 多线程以及 RunLoop 学习总结 基础知识 什么...

  • juc-Lock系列收藏

    Java多线程进阶(十一)—— J.U.C之locks框架:StampedLock

  • 第十四周笔记分享

    Android开发高级进阶 一、多线程 二、new Thread()和ThreadPoolExceutor的区别:...

  • 2018.05.13 杂谈

    《Java 并发编程实战》终于看完了,对于多线程有了一定的理解。多线程属于进阶技术。互联网行业充满了多线程和算...

  • 多线程进阶

    1.线程死锁问题 1) dispatch_sync(dispatch_get_main_queue(), ^{ ...

  • iOS之线程组实现页面刷新

    线程与线程组 线程是iOS开发进阶必经之路,不会多线程,那你一定不是一个合格的iOSer。 多线程基础看这里:关于...

  • swift3多线程之GCD

    多线程可以说ios进阶高级程序员的必修课,swift2的时候GCD还是继承的OC中多线程的C API,在swift...

  • Java多线程系列(一)——初识多线程

    前言 无论学习哪种开发语言,多线程都是绕不开的一个知识点。在Java学习中,掌握牢固的多线程知识更是进阶高级程序员...

  • 多线程进阶研究

    1.volatile关键字 作用:主要使变量在多个线程之间可见 例如:共享变量a=0,此时有两个线程A,B同时来操...

网友评论

      本文标题:多线程进阶

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