单例模式(Singleton)在SQLite操作中的应用

本文介绍了一种使用单例模式管理SQLite数据库的方法,解决了多线程环境下SQLite数据库操作冲突的问题。通过实现数据库管理类的单例模式,确保了无论在哪条线程中获取数据库对象,都是同一对象,有效避免了Databaseislocked错误。

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

       单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说,只有一个实例是很重要的,比如最近我的一个Android项目中用到一个数据库管理类来封装SQLite读写操作。我们知道,SQLite对多线程支持并不是很好,如果两个线程同时操作数据库,会报 "Database is locked" 的错误。我想到的解决办法有两个:一是运用同步机制,比如在一个线程类中对数据库操作的部分加入 synchronized 关键字,这样就可以确保该线程类的多个实例操作数据库时不会发生冲突,但是如果两个不同的线程类的实例在同一时刻操作数据库时,用 synchronized 关键字就不处理不了了。发现 SQLiteDatabase 类中有一个 isDbLockedByOtherThreads() 方法,用来判断一个数据库对象是否被其他线程锁定。由于我每次操作数据库,都new一个SQLiteOpenHelper的实例,所以用 isDbLockedByOtherThreads() 方法的结果总是false。所以想到了第二种解决办法,也就是在数据库管理类中运用单例模式,这样就保证了无论在哪个线程中获取数据库对象,都是同一个对象,那么就可在一个线程中用 isDbLockedByOtherThreads() 方法判断数据库是否被其他线程锁定,如果是,则sleep等待,直至锁被释放。

       以下Classroomdb 类正是运用了单例模式:

 

public class Classroomdb extends SQLiteOpenHelper  {

	private static final String DATABASE_NAME = "classroom.db";
	private static final int DATABASE_VERSION = 1;
	private static final String TABLE_NAME ="classroom_info";

	private static Classroomdb instance;
	
	private Classroomdb(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}
	
	public static Classroomdb Instance(Context context) {
		if (instance == null) {
			instance = new Classroomdb(context);
		} 
		return instance;
	}

	@Override//创建表
	public void onCreate(SQLiteDatabase db) {
		String sql = "CREATE TABLE " + TABLE_NAME 
		+ " (classroom_num, building, morning1, morning2, afternoon1, afternoon2, night1);";
		Log.i("createDB=", sql);
		db.execSQL(sql);
//		db.close(); 
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub
		
	}
	
	/*
	 * 操作一
	 */
	public void update(String[] classroom_num, String[] morning1, String[] morning2, 
			String[] afternoon1, String[] afternoon2, String[] night1){
		// ......
	}

	/*
	 * 操作二
	 */
	public String[] readData(String time, String build) {
		// ......
	}
	
	/*
	 * 操作三
	 */
	public String[] getSingleClassroom(String roomNum) {
		// ......
	}

}

 

      在线程中就可如下来处理:

 

Classroomdb db = Classroomdb.Instance(context);
		while (db.getWritableDatabase().isDbLockedByOtherThreads()) {
			Log.w("dblock", "db is locked by other threads!");
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值