谈到线程同步,一般指如何对线程间共享数据的同步读写,如何避免混乱的读写结果。一个基本的解决办法就是使用锁(LOCK)。

iOS提供多种同步锁的类和方法,这里介绍下基本用法。

1. NSLock:最基本的同步锁,使用lock来获得锁,unlock释放锁。如果其它线程已经使用lock,这时lock方法会阻塞当前线程,直到其它线程调用unlock释放锁为止。NSLock锁一般用于简单的同步算法。比如生产者线程产生数据(produce),消费线程显示数据(consume),可以这样实现:

- (void)produce

{

  while (1)

  {

    [theLock lock];

    // create data

    [theLock unlock];

  }

}

- (void)consume

{

  while (1)

  {

    if ([theLock tryLock])

    {

      // display data

      [theLock unlock];

    }

    sleep(1.0); //sleep a while

  }

}

NSLock的tryLock方法可以避免阻塞当前线程,如果不能获得锁则返回NO。也可使用:

- (BOOL)lockBeforeDate:(NSDate *)limit;

设置超时返回时间。

2. NSConditionLock,即条件锁,可以设置自定义的条件来获得锁。比如上面的例子可以这样改用条件锁实现:

- (void)produce

{

  while (1)

  {

    [theLock lockWhenCondition:NO_DATA];

    // create data

    [theLock unlockWithCondition:HAS_DATA];

  }

}

- (void)consume

{

  while (1)

  {

    if ([theLock tryLockWhenCondition:HAS_DATA])

    {

      // display data

      [theLock unlockWithCondition:NO_DATA];

    }

    sleep(1.0); //sleep a while

  }

}

3. NSCondition:条件(一种信号量),类似Java中的Condition,但有所不同的是NSCondition是锁和条件的组合实现。wait方法用于线程的等待(相当于Java Condition的await()),然后通过signal方法通知等待线程(相当于Java Condition的signal()),或者broadcast通知所有等待的线程相当于Java Condition的signalAll())。一个简单生产消费同步例子:

- (void)produce

{

  [theLock lock];

  // create data

  hasData = YES;

  [theLock signal]; //这时通知调用wait的线程结束等待并返回

  [theLock unlock];

}

- (void)consume

{

  [theLock lock];

  while (!hasData)

    [theLock wait]; //注意:这时其它线程的lock调用会成功返回

  //display data

  hasData = NO;

  [theLock unlock];

}

 

4. NSRecursiveLock:递归锁,顾名思义一般用于递归程序。它可以让同一线程多次获得锁,解锁次数也必须相同,然后锁才能被其它线程获得。看下官网文档中的简单例子就能明白:

void MyRecursiveFunction(int value) 

  [theLock lock]; 

  if (value != 0) 

  { 

    --value; 

    MyRecursiveFunction(value); 

  }

  [theLock unlock];

}

当然不只用于递归程序,类似Java中的ReentrantLock。

5. @synchronized实现对象锁,类似Java中synchronized关键词。一般这样使用,但不多啰嗦了:

@synchronized(anObj) 

//......

}

iOS多线程的初步研究(二)-- 锁的更多相关文章

  1. iOS多线程的初步研究1

    iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...

  2. iOS多线程的初步研究(六)

    iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...

  3. iOS多线程的初步研究3

    iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...

  4. iOS多线程的初步研究

    iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...

  5. iOS多线程的初步研究(一)-- NSThread

    对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...

  6. iOS多线程的初步研究(六)-- NSOperation

    iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...

  7. iOS多线程的初步研究(三)-- NSRunLoop

    弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run loop可以用于处理异步事件, ...

  8. iOS多线程的初步研究(八)-- dispatch队列

    GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行,它类似NSOperationQueue但更复杂也更强大,并且可以嵌套使用.所以说,结合bloc ...

  9. iOS多线程的初步研究(十)-- dispatch同步

    GCD提供两种方式支持dispatch队列同步,即dispatch组和信号量. 一.dispatch组(dispatch group) 1. 创建dispatch组 dispatch_group_t ...

随机推荐

  1. EXCLE图形插入实例

    根据所给名称找到相应图片,并进行导入. 代码如下: Sub Import_picture() For Each shap In Sheet1.Shapes '在sheet1中的图片对象进行循环 If ...

  2. Linux环境PostgreSQL源码编译安装

    Linux环境PostgreSQL源码编译安装 Linux版本: Red Hat 6.4 PostgreSQL版本: postgresql-9.3.2.tar.gz 数据存放目录: /var/post ...

  3. Android 编译使用高版本的Java

    讨论的链接 http://bbs.csdn.net/topics/390977000 问题很容易解决,就是sdk\tools\ant\build.xml里面的配置不对,把 <property n ...

  4. Boolean.parseBoolean("true") 和 Boolean.getBoolean("true");的区别及用法

    正确用法:boolean repeatIndicator = Boolean.valueOf("true").booleanValue();或者也可以使用Boolean.parse ...

  5. SharePoint 2010 中使用Ztree和EasyUI样式冲突问题

    <style type="text/css"> /*解决ztree和SharePoint样式冲突问题*/ .ztree li a { display: inline-b ...

  6. DSP280x的数模转换使用

    /*****************************************************************************Copyright: 2013File na ...

  7. 通过 CALayer 修改 UIImageView 的界面属性

    界面属性的修改是每一个开发者必须知道的,为什么我就记不住呢, shit, 又耽误了时间,为了防止再找不到,特把一些常用的 CALayer属性记在这里,顺便分享 1.设置阴影 1 imageView.l ...

  8. Teamwork——Week4 团队项目之NABC

    项目框架——NABC模型 一.N(Need需求) 我们组主要的用户对象是第三小组——UI小组的同学们,因此我们的用户需求就是他们的数据需求. 1)提供给UI小组整理好的数据库,和前一组讨论好数据结构. ...

  9. 十个优秀的C语言学习资源推荐

    学习C语言,需要一点一滴,沉下心来,找个安静的地方,泡上一杯咖啡,在浓郁的香味中一起品味她.-- Boatman Yang 人们通常认为计算机编程很烦,但是有些人却从中发现了乐趣.每一个程序员不得不跟 ...

  10. 学习JQuery的$.Ready()与OnLoad事件比较

    $(document).Ready()方法 VS OnLoad事件 VS $(window).load()方法接触JQuery一般最先学到的是何时启动事件.在曾经很长一段时间里,在页面载入后引发的事件 ...