使用 NSConditionLock 对象
NSConditionLock 对象定义了一个互斥锁,可以使用特定值来锁住和解锁。不要
把该类型的锁和条件(参见“条件”部分)混淆了。它的行为和条件有点类似,但是它们的实现非常不同。
通常,当多线程需要以特定的顺序来执行任务的时候,你可以使用一个NSConditionLock 对象,比如当一个线程生产数据,而另外一个线程消费数据。生产者执行时,消费者使用由你程序指定的条件来获取锁(条件本身是一个你定义的整形值)。当生产者完成时,它会解锁该锁并设置锁的条件为合适的整形值来唤醒消费者线程,之后消费线程继续处理数据。
NSConditionLock 的锁住和解锁方法可以任意组合使用。比如,你可以使用unlockWithCondition:和 lock 消息,或使用lockWhenCondition:和 unlock 消息。当然,后面的组合可以解锁一个锁但是可能没有释放任何等待某特定条件值的线程。
下面的例子显示了生产者-消费者问题如何使用条件锁来处理。想象一个应用程序包含一个数据的队列。一个生产者线程把数据添加到队列,而消费者线程从队列中取出数据。生产者不需要等待特定的条件,但是它必须等待锁可用以便它可以安全的把数据添加到队列。
id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA]; |
|
while(true) |
{ |
[condLock lock];
|
/* Add data to the queue. */
|
2011-11-28 | © 2011 YouMi Mobile Co. Ltd. All Rights Reserved. [71]
Threading Programming Guide
[condLock unlockWithCondition:HAS_DATA];
|
} |
因为初始化条件锁的值为 NO_DATA,生产者线程在初始化的时候可以毫无问题的获取该锁。它会添加队列数据,并把条件设置为HAS_DATA。在随后的迭代中,生产者线程可以把到达的数据添加到队列,无论队列是否为空或依然有数据。唯一让它进入阻塞的情况是当一个消费者线程充队列取出数据的时候。
因为消费者线程必须要有数据来处理,它会使用一个特定的条件来等待队列。当生产者把数据放入队列时,消费者线程被唤醒并获取它的锁。它可以从队列中取出数据,并更新队列的状态。下列代码显示了消费者线程处理循环的基本结构。
while (true) |
{ |
[condLock lockWhenCondition:HAS_DATA];
|
/* Remove data from the queue. */
|
[condLock unlockWithCondition:(isEmpty ? NO_DATA : HAS_DATA)]; |
|
// Process the data locally.
|
} |