美文网首页Android
多线程—死锁

多线程—死锁

作者: 似焰如火 | 来源:发表于2020-02-10 10:16 被阅读0次

1. 啥是死锁

好比有两个线程,T1和T2,有两把锁L1和L2。目前程序运行状态是这样的,T1拿了锁L1,T2拿了锁L2,而且T1企图再拿第二把锁L2,T2则企图拿第一把锁L1。但是他们各自都没有把已有的锁释放,于是便各自进入阻塞等待。你等我释放,我等你释放,我俩谁都不先放,这样就陷入僵持,造成死锁。

2. 看个死锁的例子

该例子引用于:https://blog.csdn.net/ch853199769/article/details/88528748

"ActivityManager" prio=5 tid=12 Blocked
  ...
  at ActivityManagerService.updateCpuStatsNow(ActivityManagerService.java:3107)
  - waiting to lock <0x0037ca7c> (aandroid.util.SparseArray) held by thread 135
  - locked <0x0dfe4378> (a com.android.internal.os.ProcessCpuTracker)
  - locked <0x064e7a29> (a com.android.internal.os.BatteryStatsImpl)
  at AppErrors.appNotResponding(AppErrors.java:983)
  at ActivityManagerService$17.run(ActivityManagerService.java:13416)
  at android.os.Handler.handleCallback(Handler.java:793)
  at android.os.Handler.dispatchMessage(Handler.java:98)
  at android.os.Looper.loop(Looper.java:173)
  at android.os.HandlerThread.run(HandlerThread.java:65)
  at com.android.server.ServiceThread.run(ServiceThread.java:46)

"Binder:1328_15" prio=5 tid=135 Blocked
  ...
  at BatteryStatsService.noteEvent(BatteryStatsService.java:422)
  - waiting to lock <0x064e7a29> (acom.android.internal.os.BatteryStatsImpl) held by thread 12
  at ActivityManagerService.updateProcessForegroundLocked(ActivityManagerService.java:23108)
  at ActivityManagerService.importanceTokenDied(ActivityManagerService.java:8177)
  - locked <0x0ef100c6> (a ActivityManagerService)
  - locked <0x0037ca7c> (a android.util.SparseArray)
  at ActivityManagerService$13.binderDied(ActivityManagerService.java:8209)
  at android.os.BinderProxy.sendDeathNotice(Binder.java:842)
————————————————
版权声明:本文为CSDN博主「安德路」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ch853199769/article/details/88528748

先解释一下trace的含义,有些在本例中并未出现,也一起介绍

  • prio: 代表线程优先级
  • tid: java线程id
  • Blocked:线程阻塞,指当前线程执行过程中,所需要的资源长时间等待却一直未能获取到,被容器的线程管理器标识为阻塞状态,可以理解为等待资源超时的线程。
  • waiting to lock <0x00000000a2b4f3a>: 线程在等待给这个 0x00000000a2b4f3a 地址上锁
  • Deadlock:死锁,多个线程调用间,进入相互资源占用,导致一直等待无法释放
  • Runnable:线程正在执行中,该线程占用资源,正在进行某种操作
  • waiting for monitor entry”说明此线程通过 synchronized(obj) {……} 申请进入了临界区,从而进入了下图1中的“Entry Set”队列,但该 obj 对应的 monitor 被其他线程拥有,所以本线程在 Entry Set 队列中等待
  • Waiting on condition:等待资源,或等待某个条件的发生。具体原因需结合 stacktrace来分析。(1) 如果堆栈信息明确是应用代码,则证明该线程正在等待资源。一般是大量读取某资源,且该资源采用了资源锁的情况下,线程进入等待状态,等待资源的读取。又或者,正在等待其他线程的执行等。(2) 如果发现有大量的线程都在处在 Wait on condition,从线程 stack看,正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。(3) 另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。
  • TIMED_WAITING (parking):指等待状态,但这里指定了时间,到达指定的时间后自动退出等待状态;parking指线程处于挂起中。
  • 以上内容引用于https://www.cnblogs.com/kabi/p/5073706.html

本例中,两个线程ActivityManager和Binder,线程ActivityManager处于Blocked,waiting to lock <0x0037ca7c> (aandroid.util.SparseArray) held by thread 135,从这句来看是等待上锁,但该锁被thread 135占有。再看线程Binder,同样的问题,waiting to lock <0x064e7a29> (acom.android.internal.os.BatteryStatsImpl) held by thread 12,等待thread 12释放锁,也就是线程ActivityManager。显然,这就是死锁了。

相关文章

  • Java自学-多线程 死锁

    Java 演示多线程死锁 当业务比较复杂,多线程应用里有可能会发生死锁 步骤 1 : 演示死锁 线程1 首先占有对...

  • Java并发案例01---多线程之死锁

    多线程之死锁案例一

  • jstack命令:教你如何排查多线程问题

    这是之前的一个死锁案例: 一个多线程死锁案例,如何避免及解决死锁问题? 如程序中发生这样的死锁问题该如何排查呢?我...

  • 并发编程情况下几个相应问题简介

    1.并发编程的挑战之死锁 ​ 死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多...

  • 5. 死锁

    线程死锁 死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序...

  • 多线程分析——死锁代码demo

    前言 本文主要是对Java多线程死锁代码demo的分析,对其过程以及死锁进行了大致的概括,希望对大家有帮助。 死锁...

  • 面试官:连多线程问题你都一问三不知,还要我怎么“放水”?

    面试官:问你几个多线程相关的问题吧,说一下导致线程死锁的原因,怎么解除线程死锁? 程序员阿里:这个...死锁......

  • 线程同步中的死锁

    何为死锁 多线程各自持有不同的锁,并互相试图获取对方已持有的锁,导致无限等待的状况,称为死锁。比如: 避免死锁 避...

  • iOS多线程总结

    多线程 优缺点,实际应用多线程比较死锁:使用同步sync,向同一个/当前的串行队添加任务,会产生死锁新等旧,旧等新...

  • 6. 使用synchronized实现死锁

    死锁定义 死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序...

网友评论

    本文标题:多线程—死锁

    本文链接:https://www.haomeiwen.com/subject/ehrmactx.html