Android Sqlite 数据库多线程操作

最近开发中,需要再多线程中操作数据库,但是Android的sqlite数据库是不能多线程写读写的。
先看一下报的错误:

 android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: PRAGMA journal_mode
   at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)

看一下代码

public class DBTestActivity extends BaseActivity {


    private Button mAddStudent_bt;


    @Override
    protected void initView() {
        setContentView(R.layout.ac_dbtest);
        mAddStudent_bt=(Button)findViewById(R.id.ac_add_student_bt);
        mAddStudent_bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                addStudent();
            }
        });

    }

    private void addStudent() {
        //模拟1000个线程 加入数据库
        for(int i=0;i<1000;i++){
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    try {
                        //随机休眠3秒以内的时间
                        Thread.sleep((long) (Math.random( )*1000*3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } 
                    Student s=new Student();
                    s.setStudentAge("1");
                    s.setStudentName("name:"+ new Date().getTime());
                    StudentDao.getInstance().addStudent(s);
                } 
            }.start();

        }

    }
}


public class StudentDao { 
    private static  volatile  StudentDao dao;   
    public static final String TAG="StudentDao"; 
    private StudentDao(){ 
    }

    public static  StudentDao getInstance(){
        if(dao==null){
            synchronized (StudentDao.class){
                if(dao==null){
                    dao=new StudentDao(); 
                }
            }
        }
        return dao;
    }

  //添加学生的方法,会在多个线程中调用
    public void addStudent(Student student){ 
        ContentValues contentValues=new ContentValues();
        contentValues.put("s_id", UUID.randomUUID().toString());
        contentValues.put("s_name", student.getStudentName());
        contentValues.put("s_age",student.getStudentAge()); 
        DbManager dBManager=new DbManager(BaseApp.getBaseApplicationContext());
        SQLiteDatabase writableDatabase  = dBManager.getWritableDatabase();
        long result=  writableDatabase.insertOrThrow("student",null,contentValues);//这里返回行号
        Log.e(TAG, "执行的结果" +result+" "+Thread.currentThread().getName());
        writableDatabase.close();

    }
}

为了解决这个问题,我把所有的写操作放在一个线程里,保证每次调用写操作都只有一个线程,那么所有的 写方法都必须枷锁。
另外翻了一下资料,发现这个sqlite 的锁是库级别的,所以当有多个线程的时候就会涉及到同步问题。
我在dao层写了一个单线程的线程池,所有的写的操作的方法在这个线程池里调用,就ok了。
代码如下

public class StudentDao {

    private static volatile StudentDao dao;


    private static ExecutorService singThread
    public static final String TAG = "StudentDao";


    private StudentDao() {


    }

    public static StudentDao getInstance() {
        if (dao == null) {
            synchronized (StudentDao.class) {
                if (dao == null) {
                    dao = new StudentDao();
                    singThread= Executors.newSingleThreadExecutor();
                }
            }
        }
        return dao;
    }


    public void addStudent(final  Student student) {
        Runnable runnable=new Runnable() {
                @Override
                public void run() {
                    ContentValues contentValues = new ContentValues();
                    contentValues.put("s_id", UUID.randomUUID().toString());
                    contentValues.put("s_name", student.getStudentName());
                    contentValues.put("s_age", student.getStudentAge());
                    DbManager dBManager = new DbManager(BaseApp.getBaseApplicationContext());
                    SQLiteDatabase writableDatabase = dBManager.getWritableDatabase();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    long result = writableDatabase.insertOrThrow("student", null, contentValues);//这里返回行号
                    Log.e(TAG, "执行的结果1  " + result + " " + Thread.currentThread().getName());
                    writableDatabase.close();
                }
            };

        singThread.execute(runnable);

    }


    
}

简单测试了一下,还没有出现了报错的问题,可能是我的数据比较小吧,找个机会多用点数据再测试一下。这种做法只是想的到一个临时解决办法,并不能够做为方法放在项目里,如果有好的方案,可以留言告诉我一下,谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,389评论 25 707
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,121评论 29 470
  • 青年手里拿着一支香烟 名为“蓝色的爱” 尼古丁的气息不重 却多了几分忧郁 地上的烟头已有好几 是因外头的雨下了太久...
    清水Lee阅读 198评论 0 0
  • 断舍离的理念 断=阻断(不买当前不需要的东西) 舍=舍弃(扔掉当前不需要的东西) 离=脱离(脱离对东西的杂念,只挑...
    ba帝儿阅读 191评论 0 0
  • 2017年5月26日 阴 无意间和小伙伴闲聊,勾起了曾经的一段往事,若不是毫无防备它就跳了出来,我差点就彻底忘记...
    东尼日记阅读 252评论 0 0