java – SQLite连接池

我想在
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();
            }
        }
    }

}

最佳答案 有用的相关主题,接受的答案专门解决多线程访问:

What are the best practices for SQLite on Android?

点赞