【问题标题】:synchronization with executorService与 executorService 同步
【发布时间】:2015-11-05 02:09:31
【问题描述】:

我编写了以下方法来使用线程插入记录,但在运行时我收到“[SQLITE_BUSY] 数据库文件已锁定(数据库已锁定)”错误,我认为可能是由于冲突 sqlite 语句。

我只想知道我在“insertRecord”方法中正确使用了执行器服务?是否还有其他变量应该已同步?

代码

public void insertRecord(String nodeID, String lat, String lng, String xmlpath) throws SQLException, ClassNotFoundException {

    if (this.isTableExists(this.TABLE_NAME)) {

        InsertRun insRun = new InsertRun(this.psInsert, nodeID, lat, lng, xmlpath);
        this.executor.execute(insRun);

    } else {
        Log.e(TAG, "insertRecord", "table: ["+this.TABLE_NAME+"] does not exist");
    }
}

public void flush() throws SQLException {
    this.psInsert.executeBatch();

    this.psInsert.close();
    this.connInsert.close();

    Log.d(TAG, "insertRecord", "the rest of the records flushed into data base table.");
}

private class InsertRun implements Runnable {

    private PreparedStatement psInsert = null;
    private String nodeID;
    private String lat;
    private String lng;
    private String xmlPath;

    public InsertRun(PreparedStatement psInsert, String nodeID, String lat, String lng, String xmlpath) {
        // TODO Auto-generated constructor stub
        this.psInsert = psInsert;
        this.nodeID = nodeID;
        this.lat = lat;
        this.lng = lng;
        this.xmlPath = xmlpath;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            this.psInsert.setString(1, this.nodeID);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            this.psInsert.setString(2, this.lat);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            this.psInsert.setString(3, this.lng);
        } catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            this.psInsert.setString(4, this.xmlPath);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            this.psInsert.addBatch();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        synchronized(this) {
            if (++batchCnt == SysConsts.BATCH_SIZE) {
                try {
                    this.psInsert.executeBatch();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                batchCnt = 0;

                Log.d(TAG, "InsertRun", SysConsts.BATCH_SIZE+" records inserted.");
            }
        }

    }

}

【问题讨论】:

    标签: java multithreading sqlite synchronized executorservice


    【解决方案1】:

    SQLite 不是适合并发访问的数据库。您不能同时修改数据库:

    多个进程可以同时打开同一个数据库。多个进程可以同时执行 SELECT。但是,任何时候只有一个进程可以对数据库进行更改。

    .

    当 SQLite 尝试访问被另一个进程锁定的文件时,默认行为是返回 SQLITE_BUSY

    阅读this 了解详情(并在您的应用中放弃多线程...)

    【讨论】:

      【解决方案2】:

      此外,如果不了解很多关于程序的更多信息,可能很难提供良好的并发设计考虑。如果您打算编写更多的多线程应用程序,建议仔细阅读Java Concurrency in Practice

      【讨论】:

        猜你喜欢
        • 2015-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 2014-06-27
        • 1970-01-01
        相关资源
        最近更新 更多