ios专题 -线程互斥与同步
【原创】http://www.cnblogs.com/luoguoqiang1985
今天遇见了这问题,决定要需要讨论下。
线程同步的方法:
- @synchronized
官方文档解释:The @synchronized directive is a convenient way to create mutex locks on the fly in Objective-C code.
个人理解:@synchronized关键字提供了互锁功能。
示例代码:
static NSObject *lockObj = nil;
if (lockObj == nil) {
lockObj = [[NSObject alloc] init];
}
dispatch_async(dispatch_get_global_queue(, ), ^{
NSLog(@"A thread try lock!");
@synchronized(lockObj) {
NSLog(@"A thread lock, please wait!");
[NSThread sleepForTimeInterval:];
NSLog(@"A thread unlock!");
}
});
dispatch_async(dispatch_get_global_queue(, ), ^{
NSLog(@"B thread try lock!");
@synchronized(lockObj) {
NSLog(@"B thread lock, please wait!");
[NSThread sleepForTimeInterval:];
NSLog(@"B thread unlock!");
}
});
执行结果:
2013-12-28 21:11:02.332 Objc[1341:1b03] A thread try lock!
2013-12-28 21:11:02.335 Objc[1341:1b03] A thread lock, please wait!
2013-12-28 21:11:02.332 Objc[1341:3907] B thread try lock!
2013-12-28 21:11:12.336 Objc[1341:1b03] A thread unlock!
2013-12-28 21:11:12.336 Objc[1341:3907] B thread lock, please wait!
2013-12-28 21:11:17.337 Objc[1341:3907] B thread unlock!
实验结果已经证明同步效果不错!
- NSLock
官方解释:An NSLock object is used to coordinate the operation of multiple threads of execution within the same application. An NSLock object can be used to mediate access to an application’s global data or to protect a critical section of code, allowing it to run atomically.
个人理解:在一个应用里面协调线程间的执行。
示例代码:
昨晚键盘突然坏了,郁闷啊,早上赶紧入货。继续写博了。
static NSLock *lockMain = nil;
if (lockMain == nil) {
lockMain = [[NSLock alloc] init];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lockMain lock];
NSLog(@"A thread begin +!");
[NSThread sleepForTimeInterval:10];
NSLog(@"A thread + done and unlock!");
[lockMain unlock];
[lockMain lock];
NSLog(@"A thread begin -!");
[NSThread sleepForTimeInterval:10];
NSLog(@"A thread - done and unlock!");
[lockMain unlock];
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lockMain lock];
NSLog(@"B thread begin *!");
[NSThread sleepForTimeInterval:10];
NSLog(@"B thread * done and unlock!");
[lockMain unlock];
[lockMain lock];
NSLog(@"B thread begin /!");
[NSThread sleepForTimeInterval:10];
NSLog(@"B thread / done and unlock!");
[lockMain unlock];
});
执行结果:
2013-12-29 14:37:44.808 Objc[1219:1303] A thread begin +!
2013-12-29 14:37:54.811 Objc[1219:1303] A thread + done and unlock!
2013-12-29 14:37:54.812 Objc[1219:1d03] B thread begin *!
2013-12-29 14:38:04.813 Objc[1219:1d03] B thread * done and unlock!
2013-12-29 14:38:04.813 Objc[1219:1303] A thread begin -!
2013-12-29 14:38:14.815 Objc[1219:1303] A thread - done and unlock!
2013-12-29 14:38:14.816 Objc[1219:1d03] B thread begin /!
2013-12-29 14:38:24.817 Objc[1219:1d03] B thread / done and unlock!
- NSConditionLock
官方解释:
The NSConditionLock class defines objects whose locks can be associated with specific, user-defined conditions. Using an NSConditionLock object, you can ensure that a thread can acquire a lock only if a certain condition is met. Once it has acquired the lock and executed the critical section of code, the thread can relinquish the lock and set the associated condition to something new. The conditions themselves are arbitrary: you define them as needed for your application.
个人理解:
根据条件加锁与解锁。
示例代码:
static NSConditionLock *cdtLock = nil;
#define A_THREAD 1
#define B_THREAD 2
#define C_THREAD 3 __block NSInteger a = B_THREAD;
if (cdtLock == nil) {
cdtLock = [[NSConditionLock alloc] initWithCondition:a];
} dispatch_async(dispatch_get_global_queue(, ), ^{
NSLog(@"A thread run!");
BOOL canLock = [cdtLock tryLockWhenCondition:A_THREAD];
if (!canLock) {
NSLog(@"A Thread Lock fail,exit!");
return ;
}
NSLog(@"A thread begin lock!");
[NSThread sleepForTimeInterval:];
NSLog(@"A thread unlock!");
[cdtLock unlock];
}); dispatch_async(dispatch_get_global_queue(, ), ^{
NSLog(@"B thread run!");
BOOL canLock = [cdtLock tryLockWhenCondition:B_THREAD];
if (!canLock) {
NSLog(@"B Thread Lock fail,exit!");
return ;
}
NSLog(@"B thread begin lock!");
[NSThread sleepForTimeInterval:];
NSLog(@"B thread unlock!");
[cdtLock unlock];
}); dispatch_async(dispatch_get_global_queue(, ), ^{
NSLog(@"C thread run!");
BOOL canLock = [cdtLock tryLockWhenCondition:C_THREAD];
if (!canLock) {
NSLog(@"C Thread Lock fail,exit!");
return ;
}
NSLog(@"C thread begin lock!");
[NSThread sleepForTimeInterval:];
NSLog(@"C thread unlock!");
[cdtLock unlock];
});
执行结果:
2013-12-29 20:46:27.426 Objc[6282:1303] A thread run!
2013-12-29 20:46:27.466 Objc[6282:1303] A Thread Lock fail,exit!
2013-12-29 20:46:27.426 Objc[6282:1e03] C thread run!
2013-12-29 20:46:27.468 Objc[6282:1e03] C Thread Lock fail,exit!
2013-12-29 20:46:27.426 Objc[6282:1c03] B thread run!
2013-12-29 20:46:27.481 Objc[6282:1c03] B thread begin lock!
- NSRecursiveLock 递归锁
官方文档:
NSRecursiveLock defines a lock that may be acquired multiple times by the same thread without causing a deadlock, a situation where a thread is permanently blocked waiting for itself to relinquish a lock. While the locking thread has one or more locks, all other threads are prevented from accessing the code protected by the lock.
个人理解:
同一个线程可以多次请求加锁,但不会引起死锁。
示例代码:
static NSRecursiveLock *lock;
if (lock == nil) {
lock = [[NSRecursiveLock alloc] init];
}
void (^__block DoLog)(int) = ^(int value){
[lock lock];
if (value > ) {
DoLog(value-);
}
NSLog(@"value is %d", value);
[lock unlock];
};
dispatch_async(dispatch_get_global_queue(, ), ^{
NSLog(@"test begin");
DoLog();
NSLog(@"test end");
});
执行结果:
2013-12-29 21:15:31.567 Objc[6741:1303] test begin
2013-12-29 21:15:31.570 Objc[6741:1303] value is 0
2013-12-29 21:15:31.571 Objc[6741:1303] value is 1
2013-12-29 21:15:31.574 Objc[6741:1303] value is 2
2013-12-29 21:15:31.575 Objc[6741:1303] value is 3
2013-12-29 21:15:31.576 Objc[6741:1303] value is 4
2013-12-29 21:15:31.577 Objc[6741:1303] value is 5
2013-12-29 21:15:31.578 Objc[6741:1303] test end
block竟然也可以递归调用,神奇!
ios专题 -线程互斥与同步的更多相关文章
- C++线程互斥、同步
一.线程互斥 如果多个线程需要访问且可能修改同一个变量,那么需要加锁,保证同一时刻只有一个线程可以访问,这个动作即最小“原子操作” 方式1: 使用c++提供的类mutex,lock,unlock即可 ...
- Linux高级编程--09.线程互斥与同步
多个线程同时访问共享数据时可能会冲突,比如两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成: 从内存读变量值到寄存器 寄存器的值加1 将寄存器的值写回内存 假设两个线程在多处理器平台 ...
- 【原】iOS多线程之线程间通信和线程互斥
线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...
- c++并发编程之线程的互斥与同步
什么是线程的同步与互斥? 互斥:指在某一时刻指允许一个进程运行其中的程序片,具有排他性和唯一性. 对于线程A和线程B来讲,在同一时刻,只允许一个线程对临界资源进行操作,即当A进入临界区对资源操作时,B ...
- JAVA多线程提高二:传统线程的互斥与同步&传统线程通信机制
本文主要是回顾线程之间互斥和同步,以及线程之间通信,在最开始没有juc并发包情况下,如何实现的,也就是我们传统的方式如何来实现的,回顾知识是为了后面的提高作准备. 一.线程的互斥 为什么会有线程的互斥 ...
- python多线程编程(3): 使用互斥锁同步线程
问题的提出 上一节的例子中,每个线程互相独立,相互之间没有任何关系.现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些处理,然后将num加1.很容易写出这样的 ...
- Python之多线程:线程互斥与线程同步
一.锁在多线程中的使用:线程互斥 lock = threading.Lock()#创建一个锁对象 1.with lock: pass 和进程使用的方式相同 2.控制线程结束的时间 通过一个全局变量 ...
- 【Java并发专题之三】Java线程互斥、协作原理
(I)Java线程互斥原理之synchronized原理 从JDK5引入CAS原子操作,但没有对synchronized关键字做优化,而是增加了J.U.C.concurrent,concurrent包 ...
- Linux 线程间的同步与互斥
在线程并发执行的时候,我们需要保证临界资源的安全访问,防止线程争抢资源,造成数据二义性. 线程同步: 条件变量 为什么使用条件变量? 对临界资源的时序可控性,条件满足会通知其他等待操作临界资源的线程, ...
随机推荐
- ASCII,Unicode和UTF-8字符编码
ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte).也就是 ...
- Git起步--git安装与初次运行git前配置
在你开始使用 Git 前,需要将它安装在你的计算机上. 即便已经安装,最好将它升级到最新的版本. 你可以通过软件包或者其它安装程序来安装,或者下载源码编译安装. 一.Git安装 1. 在linux上安 ...
- 现代Web的资源/类型/元素--发展趋势
5月6日,谷歌开发者中心推出了一个 Web 开发最佳实践手册.伯乐在线资源频道摘编该资源后,已邀请一些关注 Web 开发的朋友参与翻译手册. 由于译者朋友几乎都是已在职,都是在工作之余参与,每位的翻译 ...
- win8下Oracle 12c 创建新用户并分配表空间
这个应该算还是比较简单吧,找了个博客照着搞,有点不同的地方改改,自己再记录下. 步骤是这样: 1.先用SYSTEM登录SOL Plus, 2.创建一个临时表空间,再创建一个表空间,然后再创建一个用户 ...
- 《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的分布
在讨论连续型随机变量函数的分布时,我们从一般的情况中(讨论正态分布的文章中提及),能够得到简化版模型. 回忆利用分布函数和概率密度的关系求解随机变量函数分布的过程,有Y=g(x),如果g(x)是严格单 ...
- 使用 Visual Studio 生成通用的 XAML 应用程序 (Windows Phone 和 Windows 通用程序)
在Build会议上,我们发布了新的版本---Windows Phone 8.1. Windows 8.1 平台.作为开发人员,这意味着您现在可以生成 XAML 和 HTML 的通用程序,并通过分享大量 ...
- 在终端中创建一个简单的mysql表格
打开终端后输入:/usr/local/MySQL/bin/mysql -u root –p 然后输入密码:***** 创建数据库:create database work; 使用当前数据库:use w ...
- onethink加密解密函数
onethink中封装的加密解密函数 <?php /** * 系统加密方法 * @param string $data 要加密的字符串 * @param string $key 加密密钥 * @ ...
- PAT 1016. Phone Bills
A long-distance telephone company charges its customers by the following rules: Making a long-distan ...
- NIO组件Selector调用实例
*对于nio的非阻塞I/O操作,使用Selector获取哪些I/O准备就绪,注册的SelectionKey集合记录关联的Channel这些信息.SelectionKey记录Channel对buffer ...