没有合适的资源?快使用搜索试试~ 我知道了~
Android SQLite3多线程操作问题研究总结
1 下载量 56 浏览量
2021-01-20
09:55:30
上传
评论
收藏 79KB PDF 举报
温馨提示
试读
2页
最近做项目时在多线程读写数据库时抛出了异常,这自然是我对SQlite3有理解不到位的地方,所以事后仔细探究了一番。 1.关于getWriteableDataBase()和getReadableDatabase()的真正作用 getWriteableDataBase()其实是相当于getReadableDatabase()的一个子方法,getWriteableDataBase()是只能返回一个以读写方式打开的SQLiteDatabase的引用,如果此时数据库不可写时就会抛出异常,比如数据库的磁盘空间满了的情况。而getReadableDatabase()一般默认是调用getWriteableDa
资源详情
资源评论
资源推荐
Android SQLite3多线程操作问题研究总结多线程操作问题研究总结
最近做项目时在多线程读写数据库时抛出了异常,这自然是我对SQlite3有理解不到位的地方,所以事后仔细探究了一番。
1.关于关于getWriteableDataBase()和和getReadableDatabase()的真正作用的真正作用
getWriteableDataBase()其实是相当于getReadableDatabase()的一个子方法,getWriteableDataBase()是只能返回一个以读写
方式打开的SQLiteDatabase的引用,如果此时数据库不可写时就会抛出异常,比如数据库的磁盘空间满了的情况。而
getReadableDatabase()一般默认是调用getWriteableDataBase()方法,如果数据库不可写时就会返回一个以只读方式打开的
SQLiteDatabase的引用,这就是二者最明显的区别。
关键源码如下:
public synchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// darn! the user closed the database by calling mDatabase.close()
mDatabase = null;
} else if (!mDatabase.isReadOnly()) {
return mDatabase; // The database is already open for business
}
}
... ...
public synchronized SQLiteDatabase getReadableDatabase() {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// darn! the user closed the database by calling mDatabase.close()
mDatabase = null;
} else {
return mDatabase; // The database is already open for business
}
}
... ...
try {
return getWritableDatabase();
}
... ...
2.SQLiteDatabase的同步锁的同步锁
其实在只使用一个SQLiteDatabase的引用时,SQLiteDatabase对CRUD操作都会加上一个锁(因为是db文件,所以精确至数据
库级),这就保证了在同一时间你只能进行一项操作,无论是不是在同一个线程中,这就导致了如果你在程序中对
SQLiteOpenHelper使用了单例模式,那么你对数据库读写进行任何的优化操作都是”徒劳”。
3.多线程读数据库多线程读数据库
仔细看源码你会发现,在数据库操作中只有add,delete,update会调用lock(),而query()是不会调用的,但是在加载数据时,调用
了SQLiteQuery的fillWindow方法,而该方法依然会调用SQLiteDatabase.lock(),所以要想真正的实现多线程读数据库,只能
每个线程使用各自的SQLiteOpenHelper对象进行读操作,这样就可避开同步锁。关键源码如下:
/* package */ int fillWindow(CursorWindow window,
int maxRead, int lastPos) {
long timeStart = SystemClock.uptimeMillis();
mDatabase.lock();
mDatabase.logTimeStat(mSql, timeStart, SQLiteDatabase.GET_LOCK_LOG_PREFIX);
try {... ...
4.多线程读写多线程读写
实现多线程读写的关键是enableWriteAheadLogging属性,这个方法 API Level 11添加的,也就是所3.0以上的版本就基本不
可能实现真正的多线程读写了。简单的说通过调用enableWriteAheadLogging()和disableWriteAheadLogging()可以控制该数
据是否被运行多线程读写,如果允许,它将允许一个写线程与多个读线程同时在一个SQLiteDatabase上起作用。实现原理是
写操作其实是在一个单独的log文件,读操作读的是原数据文件,是写操作开始之前的内容,从而互不影响。当写操作结束后
读操作将察觉到新数据库的状态。当然这样做的弊端是将消耗更多的内存空间。
5.多线程写多线程写
这个就不用多想了,SQLite压根不支持,如果实在有需求可以使用多个数据库文件。
6.备注备注
weixin_38664556
- 粉丝: 5
- 资源: 958
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0