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 线程间的同步与互斥
在线程并发执行的时候,我们需要保证临界资源的安全访问,防止线程争抢资源,造成数据二义性. 线程同步: 条件变量 为什么使用条件变量? 对临界资源的时序可控性,条件满足会通知其他等待操作临界资源的线程, ...
随机推荐
- MFC DialogBar 按钮灰色不响应
在MFC单文档加添加DialogBar,然后在DialogBar上添加按钮,会出现如下情况,单击无响应. 解决方案: 在 CSideDialogBar头文件和CPP文件里添加如下函数 afx_msg ...
- C# TypeConverter 数据转换
提供一种将值的类型转换为其他类型以及访问标准值和子属性的统一方法. 自定义Converter: public class GenericListTypeConverter<T> : Typ ...
- Bzoj 2789: [Poi2012]Letters 树状数组,逆序对
2789: [Poi2012]Letters Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 278 Solved: 185[Submit][Stat ...
- 神经网络中误差反向传播(back propagation)算法的工作原理
注意:版权所有,转载需注明出处. 神经网络,从大学时候就知道,后面上课的时候老师也讲过,但是感觉从来没有真正掌握,总是似是而非,比较模糊,好像懂,其实并不懂. 在开始推导之前,需要先做一些准备工作,推 ...
- 构建CMDB的一些启发
开篇感言: 自从学习python自动化开发以来,一直都是从技术的角度来看待一切.以为技术就是王道.但显然我是一只井底之蛙.其实技术只不过是实现功能的工具而已,仅此而已.后来学习了解CMDB,越来越发现 ...
- 《神经网络和深度学习》系列文章十二:Hadamard积,s⊙t
出处: Michael Nielsen的<Neural Network and Deep Learning>,点击末尾“阅读原文”即可查看英文原文. 本节译者:哈工大SCIR本科生 王宇轩 ...
- Javascript数据类型——number类型
ECMAScript规范中使用IEEE754格式来表示整数和浮点数.支持十进制.八进制以及十六进制.有一点注意的是八进制数字在严格模式下是无效的,这可能会影响到程序的正常运行. 避免浮 ...
- JSBinding+Bridge:逻辑代码中操作二进制数据
以这2个函数为例 class File { public static byte[] ReadAllBytes(string path); public static void WriteAllByt ...
- java中如何使正在运行中的线程退出
终止线程的三种方法 有三种方法可以使终止线程. 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2. 使用stop方法强行终止线程(这个方法不 ...
- 【JAVA - SSM】之MyBatis与原生JDBC、Hibernate访问数据库的比较
首先来看一下原生JDBC访问数据库的代码: public static void main(String[] args) { // 数据库连接 Connection connection = null ...