解决多线程并发访问SQLite数据库

本文介绍了一种用于Android环境中多线程访问SQLite数据库的单例模式实现方法,通过AtomicInteger来跟踪数据库的打开次数,并确保在多线程环境下只创建一个数据库实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   java.lang.IllegalStateException: attempt to re-open an already-closed object

       使用单例实现:如下

  1. import android.database.sqlite.SQLiteDatabase;  
  2. import android.database.sqlite.SQLiteOpenHelper;  
  3. import java.util.concurrent.atomic.AtomicInteger;  
  4. /**  
  5.  *多线程下调用SQLite  
  6.  *   
  7.  * @author daniel  
  8.  *   
  9.  */  
  10. public class DBManager {  
  11.     //解决多线程并发  
  12.     private AtomicInteger mOpenCounter = new AtomicInteger();  
  13.     private static DBManager instance;  
  14.     private static SQLiteOpenHelper mDatabaseHelper;  
  15.     private SQLiteDatabase mDatabase;  
  16.     private DBManager(){  
  17.           
  18.     }  
  19.   
  20.     /**  
  21.      * 初始化  
  22.      * @param helper  
  23.      */  
  24.     public static synchronized void initializeInstance(SQLiteOpenHelper helper) {  
  25.         if (instance == null) {  
  26.             instance = new DBManager();  
  27.             mDatabaseHelper = helper;  
  28.         }  
  29.     }  
  30.   
  31.     /**  
  32.      * 获得当前实例对象  
  33.      * @return  
  34.      */  
  35.     public static synchronized DBManager getInstance() {  
  36.         if (instance == null) {  
  37.             throw new IllegalStateException(  
  38.                     DBManager.class.getSimpleName()  
  39.                             + " is not initialized, call initializeInstance(..) method first.");  
  40.         }  
  41.   
  42.         return instance;  
  43.     }  
  44.   
  45.     /**  
  46.      * 打开数据库对象   
  47.      * @return  
  48.      */  
  49.     public synchronized SQLiteDatabase openDatabase() {  
  50.         if (mOpenCounter.incrementAndGet() == 1) {  
  51.             // Opening new database  
  52.             mDatabase = mDatabaseHelper.getWritableDatabase();  
  53.         }  
  54.         return mDatabase;  
  55.     }  
  56.     /**  
  57.      * 多线程下关闭  
  58.      */  
  59.     public synchronized void closeDatabase() {  
  60.         if (mOpenCounter.decrementAndGet() == 0) {  
  61.             // Closing database  
  62.             mDatabase.close();  
  63.   
  64.         }  
  65.     }  


    转载自http://blog.youkuaiyun.com/dingsai88/article/details/41676373

Qt中的多线程访问SQLite数据库通常是为了利用多核处理器的能力并避免阻塞UI线程。以下是使用QThread和QSqlDatabase的一个基本步骤: 1. **创建单独的线程**:创建一个QThread子类,并在其构造函数中初始化QSqlDatabase连接。 ```cpp class DatabaseWorker : public QThread { public: DatabaseWorker(QObject *parent = nullptr) : QThread(parent), db(new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE"))) { /* 初始化数据库连接 */ } private: QSqlDatabase db; }; ``` 2. **在新线程中执行数据库操作**:在`run()`方法中,你可以执行查询或者其他长时间运行的任务。 ```cpp void DatabaseWorker::run() { if (!db.open()) { // 错误处理 emit error("Failed to open database"); return; } QSqlQuery query; query.prepare("SELECT * FROM table;"); if (query.exec()) { // 处理查询结果 while(query.next()) { emit dataReceived(query.value(0).toString()); } } else { emit error(query.lastError().text()); } } ``` 3. **信号与槽的链接**:在主线程中,通过信号槽机制监听worker线程的结果。 ```cpp connect(&databaseWorker, &DatabaseWorker::dataReceived, this, &YourClass::handleData); connect(&databaseWorker, &DatabaseWorker::error, this, &YourClass::showErrorMessage); ``` 4. **启动线程**:当需要执行数据库操作时,创建一个新的DatabaseWorker实例并启动它。 ```cpp databaseWorker.start(); ``` 注意:为了保证并发安全,确保在主线程之外的操作数据库。此外,SQLite默认在单线程环境中是安全的,但在并发环境下,如果多个线程同时打开同一数据库文件,可能会引发锁竞争问题,可以考虑使用SQLite的事务管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值