@synchronized的使用

参考文档:
[https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW1]
官方文档:

The @synchronized directive is a convenient way to create mutex locks
on the fly in Objective-C code. The @synchronized directive does what
any other mutex lock would do—it prevents different threads from
acquiring the same lock at the same time. In this case, however, you
do not have to create the mutex or lock object directly. Instead, you
simply use any Objective-C object as a lock token, as shown in the
following example:
@synchronized可以非常方便的创建互斥锁,@synchronized和其他所是一样的。@synchronized可以阻止多线程在同一时间获得相同的锁。
- (void)myMethod:(id)anObj
{
@synchronized(anObj)
{
// Everything between the braces is protected by the @synchronized directive.
}
}
The object passed to the @synchronized directive is a unique identifier used to distinguish the protected block. If you execute the preceding method in two different threads, passing a different object for the anObj parameter on each thread, each would take its lock and continue processing without being blocked by the other. If you pass the same object in both cases, however, one of the threads would acquire the lock first and the other would block until the first thread completed the critical section.
这个对象是唯一的标识符来保护这个代码块,如果你在两个线程执行这个方法,传入不同的对象,那么每个对象将会保留自己的锁继续执行,不会被另一个对象堵塞。如果你在两个两种情况下传递相同的对象,那么一个线程将会首先获得锁,另一个线程将会阻塞直到对个线程完成这个代码块。
As a precautionary measure, the @synchronized block implicitly adds an exception handler to the protected code. This handler automatically releases the mutex in the event that an exception is thrown. This means that in order to use the @synchronized directive, you must also enable Objective-C exception handling in your code. If you do not want the additional overhead caused by the implicit exception handler, you should consider using the lock classes.
以为一个预防措施,@synchronized代码块隐式的添加了异常处理来保护代码块,handler自动释放互斥锁,当异常抛出的时候。这意味着为了直接使用@synchronized,你必须可以自己捕获异常。如果你不想要@synchronized带来的额外开销,你需要使用锁对象。

从上边文档可以得出以下结论:
1.锁对象要比@synchronized效率高,因为其他锁对象没有异常处理机制。
2.@synchronized锁定的是单个对象对应的代码块。

扩展:
atomic属性锁定的一个对象的访问,包括读和写。@synchronized锁定的是代码块。这也是我们有时候必须使用@synchronized的原因。
因为:
如果我们在一个代码块中有多个原子属性的读写,而这几个原子属性如果是一体的(例如:一个属性是用户的名,一个属性对应的是姓,那么在多线程中就可能出现姓和名对应不上),那么可能就会出现数据错乱。这时候就必须使用@synchronized对代码块进行锁定,保证代码块内同时只有一个线程进行访问。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@synchronized是Objective-C中用于实现线程安全的关键字。它可以用于保护一段代码,确保同一时间只有一个线程可以执行这段代码。当你传入一个对象给@synchronized时,这个对象会与一个递归锁关联起来。递归锁是一种特殊的锁,它允许同一个线程多次对它进行加锁,而不会造成死锁。 在实现中,每个被@synchronized保护的对象都会有一个与之关联的递归锁。这个递归锁会在代码块执行之前被加锁,然后在代码块执行完毕后被解锁。这样可以确保同一时间只有一个线程可以执行被@synchronized保护的代码块。 当你传入的对象在@synchronized的代码块中被释放或者赋值为nil时,递归锁会继续保持对这个对象的引用。这是因为递归锁会在加锁时对对象进行retain操作,而在解锁时对对象进行release操作。所以即使对象被释放或者赋值为nil,递归锁仍然可以正常工作。 引用\[2\]和引用\[3\]提供了一些关于@synchronized实现的细节。在底层,使用了一个结构体SyncList来管理被@synchronized保护的对象和对应的递归锁。每个SyncList结构体都有一个指向SyncData节点链表头部的指针,以及一个用于防止多个线程对列表做并发修改的锁。SyncData结构体包含了被@synchronized保护的对象和与之关联的递归锁。每个SyncData对象也包含一个指向另一个SyncData对象的指针,形成了一个链表结构。通过这种方式,可以实现对不同对象的并发保护。 总结起来,@synchronized关键字通过与递归锁关联来实现线程安全。传入的对象会与一个递归锁关联起来,递归锁会在代码块执行前加锁,在代码块执行完毕后解锁。即使对象被释放或者赋值为nil,递归锁仍然可以正常工作。通过使用SyncList和SyncData结构体,可以管理多个被@synchronized保护的对象和对应的递归锁。 #### 引用[.reference_title] - *1* *2* *3* [@synchronized 递归锁详解](https://blog.csdn.net/u014600626/article/details/107915866)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值