【问题标题】:Android SQL database open and close - race conditionAndroid SQL 数据库打开和关闭 - 竞争条件
【发布时间】:2015-05-18 13:01:00
【问题描述】:

我有一个相当复杂的应用程序,它从各种后台线程和服务读取和写入数据库。有时(不幸的是经常)我会因为

而崩溃

尝试重新打开一个已经关闭的对象

java.lang.IllegalStateException:无法执行此操作,因为 连接池已关闭。

我已经阅读了关于这个主题的一些 SO 问题,一般建议包括根本不关闭数据库连接、关闭/打开 onCreate/onResume、在应用程序中关闭/打开、在需要执行时关闭/打开数据库等操作

我尝试的最后一件事是将我的所有打开/关闭移动到与 db 对象一起使用的实际方法中。这降低了错误的频率,但是当从不同的线程访问 2 种不同的方法时我仍然遇到问题,两者都打开数据库,但当第二个即将运行查询并期望数据库打开时关闭连接.

我知道我可以在一个公共锁对象上进行同步,因为包含我所有数据库访问方法的数据库管理器类是一个单例,但是仅仅为了打开/关闭而这样做感觉很糟糕。

有什么建议吗?

【问题讨论】:

    标签: java android mysql multithreading


    【解决方案1】:

    如果您不想同步您的数据库方法,请保持如下所示的打开和关闭方法调用次数的计数。

    int count=0;
    
    openDb(){
      if(db==null){
            //Open the db
       }
       count++;
    }
    
    public void closeDb(){
            count--;
            if(count==0){
                //close the db
            }
    }
    

    【讨论】:

    • 您仍然需要使用某种锁。例如。我有 2 个线程和 count= 1。然后一个线程调用 openDb 并通过 if 但在完成 count++ 之前被中断:数据库已经打开,count= 1。其他线程调用closeDb 并完成:数据库现在关闭,count= 0。第一个线程完成 count++:数据库仍然关闭,count= 1。因此创建了无效状态。跨度>
    • 为了避免这种竞争条件,您只能使用同步
    • 我不确定我是否理解,你到底是什么意思。你能解释一下吗?您答案中的代码没有使用我所知道的任何类型的同步。
    猜你喜欢
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 2020-12-11
    • 2013-08-12
    • 1970-01-01
    相关资源
    最近更新 更多