Java项目有中多个线程如何查找死锁
作者:沉默着忍受 发布时间:2023-01-06 06:17:35
当项目有中多个线程,如何查找死锁?
最近,在IDEA上进行多线程编程中老是在给线程加锁的时候,总是会遇到死锁问题,而当程序出现死锁问题时,编译器不能精确的显示错误的精确位置。当项目代码很多的时候, 往往会给自己添加不必要的麻烦,今天,我就分享分享几个解决方法。
1.编译环境
IDEA 2020 ,windows10, jdk8及以上版本
一、死锁是什么?
死锁指A线程想使用资源但是被B线程占用了,B线程线程想使用资源被A线程占用了,导致程序无法继续下去了。
1.1 死锁的例子;
public class Deadlock {
public static void main(String[] args) {
Object lock1 = new Object();
Object lock2 = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock1){
System.out.println("线程一得到了lock1");
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程一获取lock2");
synchronized (lock2){
System.out.println("线程一得到了lock2");
}
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock2){
System.out.println("线程二得到了lock2");
try{
//让线程2,获取锁1
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程二获取lock1");
//尝试获取lock1
synchronized (lock1){
System.out.println("线程二得到了lock1");
}
}
}
});
thread2.start();
}
}
1.2 死锁的例子;
形成死锁的条件:
1.互斥条件:(当一个资源被一个线程拥有,当被一个线程拥有后就不能被其他线程所持有)
2.请求拥有条件(一个线程所持有一个资源后又试图请求另一个资源)可修改
3.不可剥夺性:(一个资源被一个线程拥有之后,如果这个线程不释放此资源,那么其他线程不能强制获得此资源)
4.环路等待条件(多个线程在获取资源时形成一个环形链)可修改
二、使用jdk内置工具检测死锁
方法一. jconsole.exe
进入你的jdk安装路径中,打开jdk/bin/jconsole.exe
使用步骤如下:
检测结果:
方法二. jvisualvm.exe
进入你的jdk安装路径中,打开jdk/bin/jvisualvm.exe
优点:比较细,比较全面
缺点:加载有点慢!
使用步骤如下:
可以在里面看到是该项目代码的第39行出现了死锁。
方法三. jmc.exe
进入你的jdk安装路径中,打开jdk/bin/jmc.exe
优点:可以对所以死锁进行判断
缺点:没有给出解决方法
使用步骤如下:
三、死锁解决方法
通过死锁的形成条件来解决死锁问题,从根源上消除死锁。
1.请求拥有条件(一个线程所持有一个资源后又试图请求另一个资源)可修改
2.环路等待条件(多个线程在获取资源时形成一个环形链)可修改
举例修改: 方法:(修改环路等待条件)
//让线程二和线程一竞争同一个锁,修改为并行,这样避免出现环路
public class Deadlock {
public static void main(String[] args) {
Object lock1 = new Object();
Object lock2 = new Object();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock1){
System.out.println("线程一得到了lock1");
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程一获取lock2");
synchronized (lock2){
System.out.println("线程一得到了lock2");
}
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock1){ //让线程二和线程一竞争同一个锁,修改为并行,这样避免出现环路
System.out.println("线程二得到了lock1");
try{
//让线程2,获取锁1
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程二获取lock1");
//尝试获取lock1
synchronized (lock2){
System.out.println("线程二得到了lock2");
}
}
}
});
thread2.start();
}
}
四、总结
来源:https://blog.csdn.net/ILOVEMYDEAR/article/details/116027470


猜你喜欢
- 介绍在上一篇“SimpleAdapter“章节中,我们看到了把:ListView和Listview内
- 分享一个在项目中用的到文件上传下载和对图片的压缩,直接从项目中扒出来的:)package com.eabax.plugin.yundada.
- 在使用c#进行控制IIS服务启动停止的时候,提示:【无法打开计算机“.”上的 IISADMIN 服务】这种情况是发生在像vista、win7
- 本文实例为大家分享了java五子棋游戏的具体代码,供大家参考,具体内容如下AI思路:通过判断棋盘上每个空位的分数,去分数最高的几个点,随机下
- 本文实例讲述了Android实现将应用崩溃信息发送给开发者并重启应用的方法。分享给大家供大家参考,具体如下:在开发过程中,虽然经过测试,但在
- 本文实例总结了Java编程实现生成给定范围内不重复随机数的方法。分享给大家供大家参考,具体如下:在Java中的Math类中存在一个rando
- 错误Mybatis-Plus (简称MP) 是mybatis的一个增强工具,在mybatis的基础上只做增强不做改变,简化了开发效率。其实就
- Android EditText限制输入字符类型的方法总结前言:最近的项目上需要限制EditText输入字符的类型,就把可以实现这个功能的方
- 本文实例为大家分享了Android自定义轮播图的具体代码,供大家参考,具体内容如下定义Banner主要使用ViewPager实现滑动publ
- 要理解 C# 中的 volatile 关键字,就要先知道编译器背后的一个基本优化原理。比如对于下面这段代码:public class Exa
- 一、修改版本和指定生成APK文件名【可选】将项目切换到Project视图,打开app目录下的build.gradle文件1.1 修定软件版本
- Java基于对象流实现银行系统的具体代码,供大家参考,具体内容如下系统特点:数据持久化到文件中,系统启动后,加载文件中数据到集合中,相当于做
- 问题说明:IDEA编译的时候乱码,Build Output提示信息乱码�����。解决方案一:将Help—>Edit Cusuom V
- 目录一 为什么要用锁二 synchronized怎么实现的三 CAS来者何人四synchronized和CAS孰优孰劣轻量级锁重量级锁总结提
- 一条SQL使用两个foreach的问题未修改前的 SQL 语句<select id="findQuestionType_3_
- SpringBoot集成Mybatis+xml格式的sql配置文件最近一直在研究SpringBoot技术,由于项目需要,必须使用Mybati
- 以前传统的比较方式是遍历图片中的每一个像素,然后进行比对。这样的比对在少量图片的比对上虽然效率低一点,但是也没有什么不好。但是在大量图片比对
- 组件在容器(比如Jframe)中的位置和大小是由布局管理器来决定的。所有的容器都会使用一个布局管理器,通过它来自动进行组件的布局管理。种类j
- 前言最近都是Mybatis-Plus系列的小白文,算是对工作中最常使用的框架的细节扫盲。有在学习Mybatis-Plus使用的,可以关注一波
- spring boot actuator介绍Spring Boot包含许多其他功能,可帮助您在将应用程序推送到生产环境时监视和管理应用程序。