Android SQLiteDatabase是否是线程安全的?

时间:2016-03-25 12:22:52

标签: android multithreading sqlite

很多人说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不是线程安全的?

1 个答案:

答案 0 :(得分:4)

不,您处理数据的方式不是线程安全的。您可以使用原子SQL查询,如:

UPDATE table SET num = num + 1

而不是检索应用程序代码中的数据,修改它并将其存储回来。

SQLite是线程安全意味着您可以安全地同时在多个线程中使用所有SQLite函数,但这并不意味着数据库会根据您正在执行的操作自动锁定。如果你的线程在query()调用和update()调用之间的任何地方被中断,那么返回到该点的线程将意味着你之前检索的数据不再是最新的。