关于多线程访问sqlite 数据库的思考

来源:互联网 发布:淘宝开店提升流量 编辑:程序博客网 时间:2024/05/17 22:14

在工作中,可能你的用户并没有那么听话,随意的去点击你的按钮,如果你的按钮时间这个时候是在访问同一个sqlite 数据库,那么这个时候你可能会考虑多线程了,这里把我自己遇到的多线程访问数据库中遇到的问题总结于此:

对于单个sqlite文件打开数据库的时候要添加 synchronized 否则会提示:wait for second beause XXXis locked

这里需要一个打开数据库的方法:

<span style="font-size:14px;">public synchronized  static SQLiteDatabase geSDCardSQLiteDatabase(){</span>
<span style="font-size:14px;"><span style="white-space:pre"></span> if (db==null) {//采用单例模式 Boolean tagBoolean =FileUtils.isExists(pathString); db = SQLiteDatabase.openOrCreateDatabase(pathString , null); if (!tagBoolean) {//如果不存在那么需要创建表  db.execSQL(CreateTable.createTable()); }     }   return db;}</span>

这里讲一下为什么要用单例模式:

如果不用单例模式,那么 每次获取数据库连接的时候 都会调用  SQLiteDatabase.openOrCreateDatabase(pathString , null);  那么这时候其实就是相当于打开一个已经打开的文件,这时候自然不会成功!这个里的道理跟 synchronized   的用意应该是一样的因为当 

SQLiteDatabase.openOrCreateDatabase(pathString , null);还没有执行完成的时候又一个方法调用了,该方法 就会引起同时调用 打开自然引起错误。</span>

打开一个数据库后 因为是多线程所以 不同的方法在不同的时候会用完数据库,这里就牵扯到关闭数据库了,这里需要考虑一个方法如何保证别的方法还在用的时候不关闭数据库,因为我们用的是同一个连接,如果你关闭了,别人自然不能用,同理,你正在用的时候别人把这个连接关闭了,这个时候自然会出问题!这个时候一般报的就是

<span style="font-size:14px;">Database is closed!</span>

所以,这里需要考虑用到锁的概念了 ,保证如果有线程再用数据库连接这个连接就不会被kill 

于是:

每得到一次连接 我们都需要锁定一次

public synchronized static void lockDb()   {     //没有锁定的时候才可以更改状态   if (!isLock) {  isLock=true;  lockCount=0;//说明第一次锁定    }   lockCount++;   }

这样就能得到当前有多少个线程在使用数据库连接

那么关闭的时候我们也需要调用解锁:

   //解锁数据库public synchronized static void unLockDb()   {   lockCount--;//发现自己是最后一个那么直接 解锁   if (lockCount==0) {  isLock=false;  close();   }     }
</pre><pre name="code" class="java">public synchronized static void close()   {     //如果锁着的 那么直接 不关闭   if (!isLock) { if (db!=null) {db.close();</span> db=null; }  }   }

这样在没有线程使用连接儿的时候关闭即可!

这样就确保了,如果多个线程调用数据库那么使用的一定是一个数据库连接!那么就实现了多线程访问数据库!


以上这些或许讲的不够透彻,但是一个宗旨就是 要用就一直使用一个数据库连接 ! 这也算是个人的愚见吧!经测试,如果不用同步锁,一直使用一个连接不关闭是也可以的! 站在自己理解程度上来看,如果你有不同见解欢迎指正分享!




0 0
原创粉丝点击