CoreData和SQLite多线程访问时的线程安全问题
数据库读取操作一般都是多线程访问的。在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱。
IOS中常用的两种数据持久化存储方式:CoreData和SQLite,两者都需要设置线程安全,在这里以FMDB来解释对SQLite的线程安全访问。
一:FMDB的线程安全:(以读取图片为例)
1.没有线程安全的执行方式:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
//************** 数据库保存图片 ******************// FMDatabase *database = [FMDatabase databaseWithPath:[self getDatabasePath]]; //打开数据库 [database open]; NSString *sql = @"create table if not exists Test (id integer primary key autoincrement,name text,image blob);"; //创建表 [database executeUpdate:sql]; //把UIImage对象转化为NSData NSData *data = UIImagePNGRepresentation([UIImage imageNamed:@"user_browse"]); //写入数据 sql = @"insert into Test (name,image) values (?,?)"; [database executeUpdate:sql,@"张三",data]; //读取显示 sql = @"select * from Test;"; FMResultSet *resultSet = [database executeQuery:sql]; while (resultSet.next) { //[resultSet dataForColumn:@"image"]; NSData *imageData = [resultSet dataForColumnIndex:2]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)]; imageView.image = [UIImage imageWithData:imageData]; [self.view addSubview:imageView]; } |
2,使用线程队列
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
//************** 数据库线程安全 ***********// FMDatabaseQueue *queue = [[FMDatabaseQueue alloc] initWithPath:[self getDatabasePath]]; [queue inDatabase:^(FMDatabase *db) { //线程安全的 __block NSString *sql = @"create table if not exists Test (id integer primary key autoincrement,name text,image blob);"; //创建表 [database executeUpdate:sql]; }]; //插入数据 [queue inDatabase:^(FMDatabase *db) { //写入数据 sql = @"insert into Test (name,image) values (?,?)"; [database executeUpdate:sql,@"张三",data]; }]; //读取 [queue inDatabase:^(FMDatabase *db) { //读取显示 sql = @"select * from Test;"; FMResultSet *resultSet = [database executeQuery:sql]; while (resultSet.next) { //[resultSet dataForColumn:@"image"]; NSData *imageData = [resultSet dataForColumnIndex:2]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)]; imageView.image = [UIImage imageWithData:imageData]; [self.view addSubview:imageView]; } }]; |
分析一下线程安全下的FMDB的实现:
在当使用FMDBDatabaseQueue创建数据库时,会使用GCD创建一个线程队列:
|
1
2
3
4
5
|
。。。 _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL); dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL); _openFlags = openFlags;。。。 |
然后在读取时调用[queue inDatabase:^(FMDatabase *db)方法,在block中会锁定当前数据库
|
1
2
3
4
5
|
dispatch_sync(_queue, ^() { FMDatabase *db = [self database]; block(db); ……} |
我们可以看到实际上这里是对整个数据库进行加锁,以此来保证线程安全的。
二、CoreData的线程安全
1.没有线程安全的coredata数据读取:
NSManagedObjectContext对象的创建:_managedObjectContext = [[NSManagedObjectContext alloc] init];
插入数据操作:(AppDetailModal为数据模型)
context 为返回的 _managedObjectContext
|
1
|
AppDetailModal *newapp = [NSEntityDescription insertNewObjectForEntityForName:TableName inManagedObjectContext:context]; |
其他查询、更新、删除操作
//获取Entity
|
1
|
NSEntityDescription *entity = [NSEntityDescription entityForName:TableName inManagedObjectContext:context]; |
2.线程安全的coreData操作:
首先创建并行的NSManagedObjectContext对象
|
1
|
NSManagedObjectContext* context=[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; |
|
1
2
3
4
5
|
然后在执行读取操作时使用一下两个方法:-(void)performBlock:(void (^)(void))block-(void)performBlockAndWait:(void (^)(void))block |
|
1
2
3
4
5
|
[context performBlock:^{ //要执行的读取操作 }]; |
CoreData和SQLite多线程访问时的线程安全问题的更多相关文章
- 关于CoreData和SQLite多线程访问时的线程安全问题
数据库读取操作一般都是多线程访问的.在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱.IOS中常用的两种数据持久化存储方式:CoreData和SQLite,两 ...
- CoreData和SQLite多线程访问时的线程安全
关于CoreData和SQLite多线程访问时的线程安全问题 数据库读取操作一般都是多线程访问的.在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱.IOS中常 ...
- redis是单进程数据库,多用户排队对统一数据进行访问,不存在并发访问生产的线程安全问题
redis是单进程数据库,多用户排队对统一数据进行访问,不存在并发访问生产的线程安全问题. oracle是多进程数据库,存在并发访问的问题,必须事务加锁等方式进行处理.
- (原创)android Sqlite多线程访问异常解决方案
在开发Android的程序的时候sqlite数据库是经常用到的:在多线程访问数据库的时候会出现这样的异常:java.lang.IllegalStateException: Cannot perform ...
- C# - 多线程 之 进程与线程
并行~并发 并发 Concurrency,逻辑上的同时发生,一个处理器(在不同时刻或者说在同一时间间隔内)"同时"处理多个任务.宏观上是并发的,微观上是按排队等待.唤醒.执行的步骤 ...
- Java中类的线程安全问题
java中各种集合(字符串类)的线程安全性!!! 一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读 ...
- 逐步理解Java中的线程安全问题
什么是Java的线程安全问题? 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读/写完,其他线程才可使用.不会出现数据不一致或者数据 ...
- (转)java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- Scala中的IO操作及ArrayBuffer线程安全问题
通过Scala对文件进行读写操作在实际业务中应用也比较多,这里介绍几种常用的方式,直接上代码: 1. 从文件中读取内容 object Main { def loadData(): Array[Stri ...
随机推荐
- Java学习8——类(对象)之间的关系
(基础语法结束,开始看面向对象) 关联 关联体现的是两个类之间语义级别的一种依赖关系,比如我和我的老师. 继承(一般和特殊) 继承是指一个类继承另外一个类的的功能,并可以增加新的功能,"XX ...
- 201521123077 《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 向对象思想总结 1.2 使用常规方法总结其他上课内容 Swing一些常用组件的基本用法 Object类的clone及hashcode方法 2. 书面作业 1. clone方 ...
- Java-TreeSet的用法-入门
Java语言中,Set接口有3种通用实现:HashSet, TreeSet,LinkedHashSet.TreeSet是一种能够对内部元素进行排序的集合,它使用红黑树来存储内部元素,基于元素的值进行排 ...
- 201521123039 《java程序设计》第十一周学习总结
1. 本周学习总结 2. 书面作业 本次PTA作业题集多线程 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法实现互斥同步访问,还有 ...
- Java课程设计-定时器(团队)
一.团队介绍(没头脑和不高兴) 陈文俊[组长] 201521123047 网络1512 宣委 郑子熙 201521123045 网络1512 二.项目Git链接 定时器 三.项目git提交记录截图 四 ...
- 201521123050 《Java程序设计》第9周学习总结
1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避 ...
- 201521123030 《Java程序设计》 第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...
- Spark Streaming socketTextStream简单demo
正文 SparkStreaming的入口是StreamingContext,通过scala实现 一个简单的实时获取数据.代码SparkStreaming官网也可以找到. object SocketDS ...
- Struts2第九篇【OGNL、valueStack详解】
什么是OGNL表达式? OGNL是Object Graphic Navigation Language 是操作对象属性的开源表达式. Struts2框架使用OGNL作为默认的表达式语言. 为什么我们学 ...
- python import xxx 与 from xxx import xx 模块引入的区别
有如下脚本script1.py: A='aaaa'B='bbbb'C='cccc'print A,B,C 1.命令行交互模式下使用import 导入方式1: >>>import sc ...