synchronized 和 beginTransaction 死锁的一个例子
来源:互联网 发布:美工设计学习 编辑:程序博客网 时间:2024/06/05 19:25
这是一个及其诡异的死锁,很少有人意识到,在Androind中,SQLiteDatabase.beginTransaction的实现里,也要等到SQLiteConnectionPool中此db的primaryConnect可用才行。也就是说,beginTransaction和endTransaction也在某种程序上等同于锁定和解锁,在和synchronized(sLocker)嵌套使用时,同样要考虑死锁的问题。
一般来讲,如果看到SQLiteConnectionPool的很长的超时警告,就要考虑死锁的可能性。下面是死锁的模拟:
package com.mat.testdeadlock;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;public class MainActivity extends AppCompatActivity { static Object sLocker = new Object(); MySqlLiteHlelper myHelper; Runnable run1 = new Runnable() { @Override public void run() { try { Thread.sleep(3000); SQLiteDatabase db = myHelper.getWritableDatabase(); Log.d("DEADLOCK", "Before beginTransaction"); db.beginTransaction(); Log.d("DEADLOCK", "After beginTransaction"); Thread.sleep(3000); Log.d("DEADLOCK", "Before synchronized"); synchronized (sLocker) { Log.d("DEADLOCK", "In synchronized"); } try{ db.setTransactionSuccessful(); }finally { db.endTransaction(); } } catch (Exception e) { e.printStackTrace(); } } }; Runnable run2 = new Runnable() { @Override public void run() { try { Thread.sleep(3000); Log.d("DEADLOCK", "Before synchronized"); synchronized (sLocker) { Log.d("DEADLOCK", "In synchronized"); Thread.sleep(3000); SQLiteDatabase db = myHelper.getWritableDatabase(); Log.d("DEADLOCK", "Before beginTransaction"); db.beginTransaction(); Log.d("DEADLOCK", "After beginTransaction"); try{ db.setTransactionSuccessful(); }finally { db.endTransaction(); } } } catch (Exception e) { e.printStackTrace(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myHelper = new MySqlLiteHlelper(this); } @Override protected void onStart() { super.onStart(); new Thread(run1,"Thread-1").start(); new Thread(run2,"Thread-2").start(); }}
结果:
04-22 12:28:38.473 972-1006/com.mat.testdeadlock D/DEADLOCK: Before synchronized
04-22 12:28:38.473 972-1006/com.mat.testdeadlock D/DEADLOCK: In synchronized
04-22 12:28:38.551 972-1005/com.mat.testdeadlock D/DEADLOCK: Before beginTransaction
04-22 12:28:38.551 972-1005/com.mat.testdeadlock D/DEADLOCK: After beginTransaction
04-22 12:28:41.474 972-1006/com.mat.testdeadlock D/DEADLOCK: Before beginTransaction ---此时,1005 hold db, 1006 waiting sLocker
04-22 12:28:41.552 972-1005/com.mat.testdeadlock D/DEADLOCK: Before synchronized --此时,1006 hold sLocker, 1005 waiting db
04-22 12:29:11.474 972-1006/com.mat.testdeadlock W/SQLiteConnectionPool: The connection pool for database '/data/user/0/com.mat.testdeadlock/databases/my.db' has been unable to grant a connection to thread 2462 (Thread-2) with flags 0x2 for 30.000002 seconds. Connections: 0 active, 1 idle, 0 available
.
.
.
04-22 12:41:41.488 972-1006/com.mat.testdeadlock W/SQLiteConnectionPool: The connection pool for database '/data/user/0/com.mat.testdeadlock/databases/my.db' has been unable to grant a connection to thread 2462 (Thread-2) with flags 0x2 for780.01404 seconds. Connections: 0 active, 1 idle, 0 available.
- synchronized 和 beginTransaction 死锁的一个例子
- Whatsapp ANR的一个分析,MediaProvider的 synchronized 和 beginTransaction 死锁导致的奇葩问题
- 死锁的例子和一个解决办法
- 一个死锁的例子
- java synchronized死锁的好例子
- 一个简单的死锁例子
- 一个死锁的简单例子
- 一个简单的死锁例子
- 一个死锁的简单例子
- 一个简单死锁的例子
- java死锁的一个例子
- 一个线程死锁的例子
- 一个简单的死锁例子
- 一个线程死锁的例子
- synchronized的一个简单例子
- 一个多线程的死锁和锁争用的例子
- Hibernate的getTransaction()和beginTransaction()
- SuspendThread 造成程序死锁的一个例子
- ThreadLocal与局部变量
- 马士兵java学习之路
- 分享:初涉Pysqlite遇到的问题
- 斐波那契数列
- TurtleBot基于已知地图的自主导航
- synchronized 和 beginTransaction 死锁的一个例子
- C#中SqlDataAdapter的使用小结
- windows批处理学习2--小例子
- this is my first Blog
- UE4 编译配置详解
- Java多线程:Semaphore信号量
- c#读取XML
- 176. Second Highest Salary----leetcode----寻找第二大纪录的方法
- 求最长上升子序列