线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作。
所以这里同步应该不是一起、共同完成的意思,可理解为协调就是按预定的先后次序进行工作,好比:
‘不要和我抢了,你先等会我做完了你在做’。
线程同步目的为了多个线程都能很好的工作,合理的访问系统资源不争不抢、和谐共处。iOS开发中常用的保持线程同步有以下几种:
- 通过线程加锁
- 串行队列
- GCD
### 线程加锁
常用的几种形式的锁
- 1、 @synchronized
- (void)myMethod:(id)anObj
{
@synchronized(anObj)
{
//执行的代码操作
}
}
通过***synchronized指令
***自动的添加一个互斥锁,底层通过pthread_mutex实现。通过对一段代码的使用进行加锁。其他试图执行该段代码的线程都会被阻塞,直到加锁线程退出执行该段被保护的代码段。
当在@synchronized()代码块中抛出异常的时候,Objective-C运行时会捕获到该异常,并释放信号量,并把该异常重新抛出给下一个异常处理者。
一个线程是可以以递归的方式多次调用***myMethod
***。
关于参数***anObj
***;
作为一个唯一标识符来标记当前线程加锁操作必须是个对象类型,所以对于同一个操作不同的线程应该用同一个对象,否则无法起到标记加锁的作用。 不能为空nil。
常见的基本都是***self
***
@synchronized(self)
{
//执行的代码操作
}
self作为标记符十分常见,但是很明显会有一个问题:
//方法1
- (void)myMethod1:(id)anObj
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT , 0), ^{
@synchronized(anObj)
{
//执行的代码操作
}
});
}
//方法2
- (void)myMethod2:(id)anObj
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT , 0), ^{