很多人说SQLiteDatabase是线程安全的,但是当我用这样的设置运行一些简单的测试时:
private class MyRunnable implements Runnable{
@Override
public void run() {
for(int i = 0 ;i < 100 ; i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Cursor cursor = database.query(true,"testdb",new String[]{"num"},"id=?",
new String[]{"1"},null,null,null,null);
cursor.moveToFirst();
int original = cursor.getInt(0);
ContentValues values = new ContentValues();
values.put("num",++original);
database.update("testdb",values,"id=?",new String[]{"1"});
}
}
}
MyRunnable runnable1 = new MyRunnable();
MyRunnable runnable2 = new MyRunnable();
new Thread(runnable1).start();
new Thread(runnable2).start();
在MyRunnable中,有一个循环运行100次。每次,num字段将加1,num的初始值为0.我们可以看到上面代码的预期结果是200,但我只得到197.
这是否意味着SQLiteDatabase不是线程安全的?
答案 0 :(得分:4)
不,您处理数据的方式不是线程安全的。您可以使用原子SQL查询,如:
UPDATE table SET num = num + 1
而不是检索应用程序代码中的数据,修改它并将其存储回来。
SQLite是线程安全意味着您可以安全地同时在多个线程中使用所有SQLite函数,但这并不意味着数据库会根据您正在执行的操作自动锁定。如果你的线程在query()调用和update()调用之间的任何地方被中断,那么返回到该点的线程将意味着你之前检索的数据不再是最新的。