• 石头狮子
    2018-06-16
    1. 死锁的另一个好朋友就是饥饿。死锁和饥饿都是线程活跃性问题。
    实践中死锁可以使用 jvm 自带的工具进行排查。
    2. 课后题提出的死循环死锁可以认为是自旋锁死锁的一种,其他线程因为等待不到具体的信号提示。导致线程一直饥饿。
    这种情况下可以查看线程 cpu 使用情况,排查出使用 cpu 时间片最高的线程,再打出该线程的堆栈信息,排查代码。
    3. 基于互斥量的锁如果发生死锁往往 cpu 使用率较低,实践中也可以从这一方面进行排查。

    作者回复: 很好的总结

    
     86
  • I am a psycho
    2018-06-16
    当是死循环引起的其他线程阻塞,会导致cpu飙升,可以先看下cpu的使用率。

    作者回复: 对,比如Linux上,可以使用top命令配合grep Java之类,找到忙的pid;然后,转换成16进制,就是jstack输出中的格式;再定位代码

    
     30
  • curlev3
    2018-06-26
    回答老师的问题
    可以通过linux下top命令查看cpu使用率较高的java进程,进而用top -Hp ➕pid查看该java进程下cpu使用率较高的线程。再用jstack命令查看线程具体调用情况,排查问题。

    作者回复: 非常不错

    
     15
  • 陈一嘉
    2018-06-16
    任务线程规范命名,详细记录逻辑运行日志。jstack查看线程状态。

    作者回复: 不错

    
     6
  • tracer
    2018-06-27
    看了下jconsole检测死锁功能的源码,果然也是用ThreadMXBean获取死锁线程并分组,然后打印相关线程信息的。
    
     5
  • 西鄉十六夜
    2018-07-10
    老师,面试遇到过一个很刁钻的问题。如何在jvm不重启的情况下杀死一个线程,在stop被移除后,如果线程存在死锁那是否意味着必须要修复代码再重启虚拟机呢?

    作者回复: 不知道有什么好办法,也许用我例子哪个API去找到死锁线程,想办法把死锁条件打开;但我觉得这东西不靠谱,假设真的解除死锁,你还能保证程序正确性吗,这不会是个通用解决方案

    另外,即使以前有stop方法,blocked状态的线程也是关不了的吧,它不响应你的请求的

    
     4
  • 肖一林
    2018-06-16
    初学nio的时候确实动不动就发生死锁。现在好像也没有特别好的教程,都是一些java.io的教程。很多教程跟不上技术的迭代。也可能是因为直接io编程在项目实践中偏少。

    另外,这个小程序的图片不能放大看,不知道是微信的原因还是小程序的原因。老师看到了帮忙反馈一下。

    作者回复: nio确实教程少,书籍也不好找 Java IO,NIO,NIO2好像也没引进;如果想系统学习,我建议买本 《netty实战》,Java自己的nio定位偏重于基础性API,与终端应用需求有点鸿沟

    
     3
  • jacy
    2018-06-22
    尽然可以用ThreadMXBean来抓线程死锁信息,受教了。
    循环死锁,会导致cpu某线程的cpu时间片占用率相当高,可以结合操作系统工具分析出线程号,然后用jstack分析线程

    作者回复: 不错

    
     2
  • 残阳
    2018-06-17
    以前做排查的时候看thread dump, 一般都会直接按一些关键字搜索。比如wait,lock之类,然后再找重复的内存地址。看完这遍文章之后感觉对死锁的理解更深刻。

    作者回复: 谢谢,地址也很重要

    
     2
  • vaccywen
    2019-11-04
    多执行几次jstack,如果同一个线程id多次结果都是running,而其他线程一直都是BLOCKED状态,是不是就可以判断某个持锁线程进入死循环?
    
     1
  • 豌豆逸之
    2019-08-09
    请教老师,线程饥饿的情况,有没有什么好的诊断办法?
    
     1
  • 苦行僧
    2019-02-18
    平常工作发生的死锁都发生在数据库层面,多线程并发修改同一条记录
    
     1
  • 肖一林
    2018-06-16
    一课一练:
    最典型的场景是nio的Selector类,这个类内部有三个集合,并且对这些集合做了同步。如果多个线程同时操作一个Selector,就很容易发生死锁。它的select方法会一直拿着锁,并且循环等待事件发生。如果有其他线程在修改它内部的集合数据,就死锁了。

    同样用jstack可以发现问题,找出被阻塞的线程,看它等待哪个锁,再找到持有这把锁的线程,这个线程一搬处于运行状态

    作者回复: 不错,selected key 和 cancelled key的集合不是线程安全的,我记得标准文档就建议

    
     1
  • 天王
    2019-12-24
    18 死锁产生的原因,死锁检测工具的使用,以及在实际编码的时候如何注意 1 死锁是一种程序的状态,在实体之间由于循环依赖导致彼此都处于等待之中,没有任何个体可以继续进行,死锁存在于线程与线程之间,也存在与资源独占的进程之间,比较常见的场景是多线程并发环境中的死锁,两个或者多个线程互相持有对方需要的锁,而永久处于阻塞状态。2 检测死锁可以用jstack等工具获取线程栈,然后定位相互之间的关系,找到死锁。2.1 死锁产生的demo,定义两个对象,两个线程,线程一synchronized先锁对象a再锁对象b,线程二先锁对象b,再锁a,两个线程启动,就会产生死锁 2.2 用jstack找死锁步骤 首先确定进程ID,然后用jstack pid,可以打印出具体的死锁信息 2.3 可以用java提供的标准管理api ThreadMxBean 提供了findDeadLockedThreads方法用于定位 3 如何在预防死锁 死锁产生有几个条件 互斥条件,且互斥条件是长期持有,使用结束之前,只能自己持有,别的线程用不了,循环依赖关系,两个或者多个个体之间出现了锁的链条环,实际使用注意步骤 尽量避免使用多个锁,并且只有在需要时才持有锁,如果必须使用多个锁,设计好锁的使用顺序,再者使用带超时的方法,无法获取到锁,超时执行退出逻辑,再者,通过通过静态代码分析,去查找固定的模式,进而定位可能的死锁或者竞争情况
    展开
    
    
  • Paul Shan
    2019-11-12
    死锁是两个线程相互试图获取对方独占的资源的情况。如果随机使用锁,这种情况不可避免。
    
    
  • 格非
    2019-10-12
    操作系统中学过进程死锁发成的四个必要条件:1、互斥条件,2、占有和等待条件,3、不可抢占条件,4、循环等待条件;破环这四个必要条件中的一个就可以避免发生死锁
    
    
  • 随心而至
    2019-09-18
    一:死锁的主要原因:
    不同线程获取锁的顺序不一致导致。
    二:解决方法:
    1.确保按照一定顺序获取锁,比如两个类似lockA, lockB的hash值比较,如果相等(概率很低),再添加一把另外的锁tieLock ,具体示例 参加 JCIP 10-3
    2.开放调用 不要同时获取多把锁 具体示例 参见JCIP 10-6
    3.使用定时的锁 ,tryLock() 或者tryLock(timeout)

    三:死锁检测:
    3.1 jstack pid > app.dump 然后在文件中查找线程状态(比如搜索Blocking) -> 查看等待目标 -> 对比 Monitor...
    3.2 ThreadMXBean



    展开
    
    
  • JSON
    2019-07-17
    如果是生产环境出现了死锁状态,该怎么排查问题
    
    
  • Geek_7eb30c
    2019-06-10
    老师有个问题咨询下,我在跑一个大批量数据导入数据库的程序,用线程池一批1000导入数据库,头尾用了分布式redis锁防止并发,但在倒入中还是出现锁表的情况,不知道是不是我的分布式锁放错位置,是否应该放在异步线程开启前加锁
    
    
  • QQ怪
    2019-04-01
    还有一种锁叫做活锁,可能两个线程一直在释放锁,抢占锁,互不相让,这种也是一种并发问题
    
    
我们在线,来聊聊吧