通过ANR来查看死锁
死锁通常很难查找。但是在Android我们可以ANR来得到traces.txt。在traces.txt中可以查看那些线程在wait,当然死锁的线程也在其中。这样对查找死锁大大提供了方便。
注意:方式ANR后,在手机中就会生成如下文件data\anr\traces.txt
下面直接给出实例。
文件1
DeadLockTraceActivity.java文件
package com.gameloft.robin;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
public class DeadLockTraceActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.deadlock_trace);
}
String tag="robin";
public void onResume()
{
super.onResume();
new ThreadDeadLockExample().start();
Handler handler=new Handler();
Runnable run=new Runnable(){public void run(){forceWait();}};
handler.post(run);
}
synchronized void forceWait()
{
try {
wait(60000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
文件2
ThreadDeadLockExample.java文件
package com.gameloft.robin;
import java.util.concurrent.locks.ReentrantLock;
import android.util.Log;
public class ThreadDeadLockExample{
private final ReentrantLock lockA = new ReentrantLock(true);
private final ReentrantLock lockB = new ReentrantLock(true);
String tag="robin";
void start()
{
Log.i(tag, "ThreadDeadLockExample start");
new ThreadA("ThreadA").start();
new ThreadB("ThreadB").start();
}
class ThreadA extends Thread
{
ThreadA(String name)
{
super(name);
}
public void run()
{
Log.i(tag, "try to lock A"+" in ThreadA");
lockA.lock();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(tag, "lock A successful"+" in ThreadA");
Log.i(tag, "try to lock B"+" in ThreadA");
lockB.lock();
Log.i(tag, "lock B successful"+" in ThreadA");
lockB.unlock();
Log.i(tag, "unlock B"+" in ThreadA");
lockA.unlock();
Log.i(tag, "unlock A"+" in ThreadA");
}
}
class ThreadB extends Thread
{
ThreadB(String name)
{
super(name);
}
public void run()
{
Log.i(tag, "try to lock B "+" in ThreadB");
lockB.lock();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(tag, "lock B successful"+" in ThreadB");
Log.i(tag, "try to lock A"+" in ThreadB");
lockA.lock();
Log.i(tag, "lock A successful"+" in ThreadB");
lockA.unlock();
Log.i(tag, "unlock A"+" in ThreadB");
lockB.unlock();
Log.i(tag, "unlock B"+" in ThreadB");
}
}
}
traces.txt 文件摘要
DALVIK THREADS:
"main" prio=5 tid=1 TIMED_WAIT
| group="main" sCount=1 dsCount=0 s=N obj=0x400208b8 self=0xcdf0
| sysTid=1732 nice=0 sched=0/0 cgrp=unknown handle=-1345026000
at java.lang.Object.wait(Native Method)
- waiting on <0x4a5ba4b0> (a com.gameloft.robin.DeadLockTraceActivity)
at java.lang.Object.wait(Object.java:326)
at com.gameloft.robin.DeadLockTraceActivity.forceWait(DeadLockTraceActivity.java:24)
at com.gameloft.robin.DeadLockTraceActivity$1.run(DeadLockTraceActivity.java:18)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4633)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
"ThreadB" prio=5 tid=10 WAIT
| group="main" sCount=1 dsCount=0 s=N obj=0x4a5bf868 self=0x2174f8
| sysTid=1741 nice=0 sched=0/0 cgrp=unknown handle=2192952
at java.lang.Object.wait(Native Method)
- waiting on <0x4a5bf980> (a java.lang.VMThread)
at java.lang.Thread.parkFor(Thread.java:1535)
at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
at sun.misc.Unsafe.park(Unsafe.java:317)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:200)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
at com.gameloft.robin.ThreadDeadLockExample$ThreadB.run(ThreadDeadLockExample.java:61)
"ThreadA" prio=5 tid=9 WAIT
| group="main" sCount=1 dsCount=0 s=N obj=0x4a5bf438 self=0x216858
| sysTid=1740 nice=0 sched=0/0 cgrp=unknown handle=2189720
at java.lang.Object.wait(Native Method)
- waiting on <0x4a5bf590> (a java.lang.VMThread)
at java.lang.Thread.parkFor(Thread.java:1535)
at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
at sun.misc.Unsafe.park(Unsafe.java:317)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndChec
补充:移动开发 , Android ,