通过ANR来查看死锁

时间:2021-04-03 08:30:36
 死锁很难改。但是我们 可以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.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$ThreadA.run(ThreadDeadLockExample.java:35)