博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQLite多线程操作数据库
阅读量:2389 次
发布时间:2019-05-10

本文共 2827 字,大约阅读时间需要 9 分钟。

在开发Android的程序的时候sqlite数据库是经常用到的;在多线程访问数据库的时候会出现这样的异常:java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.或 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: 或java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

这样的异常信息,Sqlite 自身是不支持多线程同时操作的,下面呢我们给出一个解决方案并列出一些项目中用到的代码。

     我们会用到AtomicInteger,一个提供原子操作的Integer的类。因为Android 依托强大的jdk在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口,由此我们可以做一个DatabaseManager 这样的类,具体代码见下面的代码块:

public class DatabaseManager {        private AtomicInteger mOpenCounter = new AtomicInteger();    private static DatabaseManager instance;      private static SQLiteOpenHelper mDatabaseHelper;      private SQLiteDatabase mDatabase;            public static synchronized void initializeInstance(SQLiteOpenHelper helper) {          if (instance == null) {              instance = new DatabaseManager();              mDatabaseHelper = helper;          }      }          public static synchronized DatabaseManager getInstance(SQLiteOpenHelper helper) {          if (instance == null) {              initializeInstance(helper);        }          return instance;      }          public synchronized SQLiteDatabase getWritableDatabase() {          if(mOpenCounter.incrementAndGet() == 1) {              // Opening new database              mDatabase = mDatabaseHelper.getWritableDatabase();          }          return mDatabase;      }          public synchronized SQLiteDatabase getReadableDatabase() {          if(mOpenCounter.incrementAndGet() == 1) {              // Opening new database              mDatabase = mDatabaseHelper.getReadableDatabase();          }          return mDatabase;      }          public synchronized void closeDatabase() {                  if(mOpenCounter.decrementAndGet() == 0) {              // Closing database              mDatabase.close();          }      }

在我们进行关闭数据库的时候判断 

mOpenCounter.decrementAndGet() == 0 (更新器管理的给定对象的字段的当前值为0)的时候才正式关闭数据库,就不会出现上述异常。用方式呢,在我们操作数据库逻辑代码中如下使用首相要取得
mDatabaseManager = DatabaseManager.getInstance(mContext);
/***     * 判断表中是否有值     */    public boolean isExistTabValus() {        boolean flag = false;        SQLiteDatabase db = mDatabaseManager.getReadableDatabase();//获取一个可读的数据库对象        Cursor curcor = null;        try {            curcor = db.rawQuery("select * from tab ", null);            while (curcor.moveToNext()) {                if (curcor.getCount() > 0) {                    flag = true;                }            }        } catch (Exception e) {            Log.e(TAG, "isExistTabValus  error");        } finally {            if (curcor != null) {                curcor.close();            }            mDatabaseManager.closeDatabase();//关闭数据库        }        return flag;    }

 

转载地址:http://msxab.baihongyu.com/

你可能感兴趣的文章
Flex 添加效果的两种方法
查看>>
Flash Builder 4字体设置
查看>>
Actionscript 3.0 笔记一
查看>>
图像处理库OpenCV参考网址
查看>>
dllimport与dllexport作用与区别
查看>>
OpenGL坐标系
查看>>
C++用new和不用new创建类对象区别
查看>>
C++ C# JAVA 创建对象
查看>>
齐次坐标的理解
查看>>
QT配置文件
查看>>
QT .pro配置文件2
查看>>
Qt 模态与非模态对话框
查看>>
Qt C++中的关键字explicit .
查看>>
qtcreator中常用快捷键
查看>>
PowerDesigner 简介
查看>>
VS2008快捷键大全
查看>>
Access 操作或事件已被禁用模式阻止
查看>>
C# 控件置于最顶层、最底层
查看>>
几个常见的压缩算法
查看>>
浮点数的存储
查看>>