be careful for sqlitedatabase access and synchronized sync block encounter deadlock

11 篇文章 0 订阅

     在开发一个android的项目时,涉及到后台线程调用RestFullservice并同时更新数据库,采用了多线程处理,为了同步两个线程,每个线程的主任务的方法上均使用了synchronized,这是个粗粒度的同步代码:在call service 的时候,并不需要进行同步,因为和另外一个线程并没有资源竞争或者等待,这个时候就进行同步显然过早的hold住了锁,不能让另外一个线程执行任务。 对此问题进行了初步处理:尽可能晚的的hold lock,尽可能早的release lock。

     整个系统只使用了一个mutex,按理讲不会出现deadlock的情况,但在后续测试中两个线程却出现了问题,一个处于wait状态,一个处于monitor状态。很明显,死锁了。(2011-2-23update, 此话有误,这两个状态并不表明一定死锁,wait,wait,parkfor都有可能,具体情况要查看线程状态 。在网上查询了synchronized的使用说明,问题依旧。后来通过debug逐渐缩小范围,最终确定了问题:发现在数据库处理的时候使用了transaction,和synchronized存在访问顺序死锁问题

 

thread1:

 db.beginTransaction

 

 synchronized(lockObj)

{

     //database operation and other task

}

db.endTransaction

 

 

thread2:

synchronized(lockObj)

{

     //insert update delete operations

}

分析:

db.begintransaction会导致sqlitedatabase 获取exclusive lock,从而使其他写操作不能进行

1.thread1进入db.beginTransaction。

2.vm切换进程,thread2执行进入sync block内部,发现不能进行写操作,等待。

3.vm切换进程,thread1请求lockObj上的锁,发现已被thread2 hold,等待。

4.死了,隐含的exclusive lock导致锁等待

有关sqlite的锁机制请可看官网

 

这里还涉及另外一个sqlite数据库问题,就是在单线程多线程下的single connection 和mult connection 的问题

有空再写。

恐有误导,欢迎斧正

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值