我想在android中有一个连接池,因为并行线程必须同时访问数据库。
Android提供了用于javax.sql连接的PooledConnection
接口。由于Android中没有正式支持SQLite的jdbc,我想到了另一种方法,即实现SQLite数据库的连接池。
您如何看待这种方法?有什么风险?我忽视了什么吗?
我的代码如下:
数据库的连接包装类:
public class PoolConnection {
protected SQLiteDatabase sqlDb;
protected long openedAt;
private static final String DB_NAME = Environment
.getExternalStorageDirectory()
+ "/data/DBNAME.sqlite";
private static final int DB_VERSION = 1;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// nothing to do here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// no upgrade planned yet
}
}
public PoolConnection(Context context) throws Exception {
sqlDb = new DatabaseHelper(context).getWritableDatabase();
openedAt = System.currentTimeMillis();
}
public boolean isAvailable() {
if (!sqlDb.isOpen() || sqlDb.inTransaction()
|| sqlDb.isDbLockedByOtherThreads()) {
return false;
} else {
return true;
}
}
public void close() throws SQLException {
sqlDb.close();
}
public SQLiteDatabase getConnection() throws SQLException {
return sqlDb;
}
public long getOpenedAt() {
return openedAt;
}
}
连接池类:
public class ConnectionPool {
protected List<PoolConnection> connections;
protected long maxIdleTime = 30 * 1000;
public ConnectionPool() {
connections = Collections
.synchronizedList(new ArrayList<PoolConnection>());
new PoolCleaner(maxIdleTime).start();
}
public PoolConnection getConnection(Context context) throws Exception {
synchronized (connections) {
PoolConnection poolCon = null;
for (PoolConnection con : connections) {
poolCon = con;
if (poolCon.isAvailable()) {
return poolCon;
}
}
}
PoolConnection con = new PoolConnection(context);
synchronized (connections) {
connections.add(con);
}
return con;
}
public void removeExpired() {
synchronized (connections) {
for (int i = (connections.size() - 1); i >= 0; i--) {
PoolConnection con = connections.get(i);
if (con.isAvailable()
&& maxIdleTime < (System.currentTimeMillis() - con
.getOpenedAt())) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
connections.remove(i);
}
}
}
}
class PoolCleaner extends Thread {
protected long cleaningInterval;
protected boolean mustStop;
public PoolCleaner(long cleaningInterval) {
if (cleaningInterval < 0) {
throw new IllegalArgumentException(
"cleaningInterval must be >= 0");
}
this.mustStop = false;
this.cleaningInterval = cleaningInterval;
setDaemon(true);
}
public void run() {
while (!mustStop) {
try {
sleep(cleaningInterval);
} catch (InterruptedException ignore) {
}
if (mustStop) {
break;
}
removeExpired();
}
}
public void halt() {
mustStop = true;
synchronized (this) {
this.interrupt();
}
}
}
}
答案 0 :(得分:2)
有用的相关主题,接受的答案专门针对多线程访问:
答案 1 :(得分:0)
在我确定没有其他可用的东西之前,我不会编写自己的连接池。 Apache Commons有一个数据库连接池类。考虑将另一种依赖性与使用自己的维护负担进行权衡。