死锁的产生场景场景如下图:
package org.example.mianshi.deadlock; import java.util.concurrent.timeunit; /** * 作者: carter * 创建日期: 2020/3/30 12:09 * 描述: 死锁例子 */ public class deadlockapp { public static void main(string[] args) { string first = "locka"; string second = "lockb"; mythread a = new mythread("a", first, second); mythread b = new mythread("b", second, first); a.start(); b.start(); try { a.join(); b.join(); } catch (interruptedexception e) { e.printstacktrace(); } } public static class mythread extends thread { private final string first; private final string second; public mythread(string name, string first, string second) { super(name); this.first = first; this.second = second; } @override public void run() { synchronized (first) { system.out.println(this.getname() + " invoke first:" + first); try { timeunit.seconds.sleep(1); synchronized (second) { system.out.println(this.getname() + " invoke second:" + second); } } catch (interruptedexception e) { e.printstacktrace(); } } } } }
1, 找出运行程序的进程id, ps -ef | grep java
2, 使用jstack pid 来分析线程的状态;
运行效果:
诊断结果:
package org.example.mianshi.deadlock; import java.lang.management.managementfactory; import java.lang.management.threadmxbean; import java.util.arrays; import java.util.concurrent.executors; import java.util.concurrent.scheduledexecutorservice; import java.util.concurrent.timeunit; /** * 作者: carter * 创建日期: 2020/3/30 12:09 * 描述: 死锁例子 */ public class deadlockapp { private static final scheduledexecutorservice threadpool = executors.newscheduledthreadpool(1); public static void main(string[] args) { checkdeadlockbythreadmxbean(); string first = "locka"; string second = "lockb"; mythread a = new mythread("a", first, second); mythread b = new mythread("b", second, first); a.start(); b.start(); try { a.join(); b.join(); } catch (interruptedexception e) { e.printstacktrace(); } } private static void checkdeadlockbythreadmxbean() { threadmxbean threadmxbean = managementfactory.getthreadmxbean(); threadpool.scheduleatfixedrate(()->{ long[] deadlockedthreads = threadmxbean.finddeadlockedthreads(); if (deadlockedthreads!=null && deadlockedthreads.length>0){ arrays.stream(deadlockedthreads) .maptoobj(id->threadmxbean.getthreadinfo(id)) .foreach(threadinfo->{ system.out.println("出现死锁的线程是:"+threadinfo); }); } }, 1, 5, timeunit.seconds); } public static class mythread extends thread { private final string first; private final string second; public mythread(string name, string first, string second) { super(name); this.first = first; this.second = second; } @override public void run() { synchronized (first) { system.out.println(this.getname() + " invoke first:" + first); try { timeunit.seconds.sleep(1); synchronized (second) { system.out.println(this.getname() + " invoke second:" + second); } } catch (interruptedexception e) { e.printstacktrace(); } } } } }
定位结果是:
1, 同一段代码尽量避免使用多个锁;
2,一定要使用多个锁,必须注意顺序;
3,尽量使用带超时时间的等待方法;
4,使用辅助工具,比如findbugs提前发现可能发生死锁的代码段,扼杀在摇篮里。
本篇回答了死锁产生的场景,定位的方法,规避的方法;
然后结合代码,实践了一把。
原创不易,转载请注明出处。
如对本文有疑问, 点击进行留言回复!!
解决idea中出现“illegal character U+200B” 问题
荐 为什么加了@Transactional注解,事务没有回滚?
Attribute ‘sklearn.linear_model._logistic.LogisticRegression.multi_class‘ must be explicitly set to
Java/Python实现 LeetCode剑指Offer 14-I.剪绳子(动态规划)
网友评论