美文网首页
iOS开发-使用多线程同步锁@synchronized()的注意

iOS开发-使用多线程同步锁@synchronized()的注意

作者: Pandakingli | 来源:发表于2019-07-15 18:07 被阅读0次

1.@synchronized原理

synchronized中传入的object的内存地址,被用作key,通过hash map对应的一个系统维护的递归锁。所以不管是传入什么类型的object,只要是有内存地址,就能启动同步代码块的效果。

2.注意事项

  • synchronized是使用的递归mutex来做同步。
 NSObject *obj = [[NSObject alloc]init];
    @synchronized (obj) {
        NSLog(@"1st sync");
        @synchronized (obj) {
            NSLog(@"2nd sync");
        }
    }

执行结果:

2019-07-15 17:59:27.398820+0800 xxtest[63251:2852986] 1st sync
2019-07-15 17:59:27.399013+0800 xxtest[63251:2852986] 2nd sync
  • @synchronized(nil)不起任何作用
    @synchronized(nil)不起任何作用,表明我们需要适当关注传入的object的声明周期,一旦置为nil之后就无法做代码同步了。
  • 慎用@synchronized(self) (尽量不要这样使用)
    不要使用@synchronized(self)。
    不少代码都是直接将self传入@synchronized当,容易导致死锁的出现。
//class A
@synchronized (self) {
    [_sharedLock lock];
    NSLog(@"code in class A");
    [_sharedLock unlock];
}

//class B
[_sharedLock lock];
@synchronized (objectA) {
    NSLog(@"code in class B");
}
[_sharedLock unlock];

原因是self很可能会被外部对象访问,被用作key来生成一锁,类似上述代码中的@synchronized (objectA)。两个公共锁交替使用的场景就容易出现死锁。

正确的做法是传入一个类内部维护的NSObject对象,而且这个对象是对外不可见的。

  • 注意粒度控制
@synchronized (sharedToken) {
    [arrA addObject:obj];
}

@synchronized (sharedToken) {
    [arrB addObject:obj];
}

使用同一个token来同步arrA和arrB的访问,虽然arrA和arrB之间没有任何联系。
应该是不同的数据使用不同的锁,尽量将粒度控制在最细的程度
应该优化成如下代码:

@synchronized (tokenA) {
    [arrA addObject:obj];
}

@synchronized (tokenB) {
    [arrB addObject:obj];
}
  • 注意内部的函数调用
    @synchronized还有个很容易变慢的场景,就是{}内部有其他隐蔽的函数调用。比如:
@synchronized (tokenA) {
    [arrA addObject:obj];
    [self doSomethingWithA:arrA];
}

doSomethingWithA内部可能又调用了其他函数,维护doSomethingWithA的工程师可能并没有意识到自己是被锁同步的,由此层层叠叠可能引入更多的函数调用,代码就莫名其妙的越来越慢了,感觉锁的性能差,其实是我们没用好。

相关文章

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • iOS开发底层相关基础知识点

    正确使用多线程同步锁@synchronized() YYKit学习笔记

  • iOS开发-使用多线程同步锁@synchronized()的注意

    1.@synchronized原理 synchronized中传入的object的内存地址,被用作key,通过ha...

  • iOS-锁-@synchronized

    @synchronized,同步锁,又名对象锁,由于其使用简单,基本上是在iOS开发中使用最频繁的锁。 使用方式如...

  • 线程锁

    探讨iOS开发中各种锁使用NSCondition实现多线程同步 NSCondition是线程同步, 阻塞线程。 取...

  • 起底多线程同步锁(iOS)

    起底多线程同步锁(iOS) 起底多线程同步锁(iOS)

  • 2.安全性

    java中多线程同步包括: synchronized 显示锁 volatile 原子变量 之所以要使用同步,是因为...

  • iOS开发中常用的锁

    锁是线程编程同步工具的基础,在iOS开发中常用的锁有以下几种: @synchronized NSLock 对象锁 ...

  • 并发编程基础与原理

    Synchronized(同步锁) 思考一个问题,锁是为了解决什么问题,锁的本质是什么?  锁的本质是在多线程使用...

  • JUC学习笔记三

    JUC学习笔记三 用于解决多线程同步问题的方式 隐式锁(synchronized) 同步代码块 同步方法 显式锁(...

网友评论

      本文标题:iOS开发-使用多线程同步锁@synchronized()的注意

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