Java死锁故障排除和解决

JavaOne年度会议的一大优点是,主题专家介绍了几个技术和故障排除实验室。 其中的一个实验室今年特别吸引了我的注意力:“ HOL6500-查找和解决Java死锁 ”,由Java冠军Heinz Kabutz提出 。 这是我在该主题上看到的最好的演示之一。 我建议您自己下载,运行和研究实验室。

本文将重温这个经典的线程问题,并总结提出的关键故障排除和解决方法。 我还将根据自己的多线程故障排除经验来扩展主题。

Java死锁:这是什么?

真正的Java死锁本质上可以描述为两个或多个线程永远被阻塞,互相等待的情况。 这种情况与其他更常见的“日常”线程问题模式(例如锁争用和线程争用,等待阻塞IO调用的线程等)截然不同。这种锁排序死锁情况可以如下所示:

在上面的可视示例中,线程A和线程B尝试以不同顺序获取2个锁是致命的。 一旦线程达到死锁状态,它们将永远无法恢复,从而迫使您重新启动受影响的JVM进程。

Heinz还描述了另一种死锁: 资源死锁 。 到目前为止,这是我在Java EE企业系统故障排除经验中最常见的线程问题模式。 资源死锁本质上是一种场景,其中一个或多个线程正在等待获取永远无法使用的资源,例如JDBC池耗尽。

锁排序死锁

您现在应该知道我是JVM线程转储分析的忠实拥护者 ; 对于参与Java / Java EE开发或生产支持的个人而言至关重要的技能。 好消息是,大多数JVM线程转储格式(HotSpot,IBM VM…)都可以很容易地对Java级别的死锁进行开箱即用的识别,因为它们包含本机死锁检测机制,该机制实际上将向您显示所涉及的线程。真正的Java级死锁场景以及执行堆栈跟踪。 可以通过您选择的工具(例如JVisualVM,jstack或本机例如基于Unix的操作系统上的kill -3 <PID>)捕获JVM线程转储。 在运行实验1之后,在JVM Java级死锁检测部分下面找到:

现在,这是简单的部分……根本原因分析工作的核心是首先了解为什么此类线程涉及死锁情况。 锁顺序死锁可能会从您的应用程序代码中触发,但是除非您参与高并发性编程,否则,可能的罪魁祸首是您正在使用的第三方API或框架或实际的Java EE容器本身(如果适用)。

现在让我们在下面回顾一下亨氏提出的锁排序死锁解决策略:

#通过全局排序解决死锁(请参阅lab1解决方案)

  • 本质上涉及对锁的全局排序的定义,它将始终防止死锁(请参阅lab1解决方案)

#TryLock解决死锁(请参阅lab2解决方案)

  • 锁定第一把锁
  • 然后尝试锁定第二把锁
  • 如果您可以锁定它,那就很好了
  • 如果不能,请再试一次

可以使用Java Lock&ReantrantLock来实现上述策略,这也使您能够灵活地设置等待超时,以防止在第一个锁获取时间太长的情况下导致线程不足。

public interface Lock {void lock();void lockInterruptibly() throws InterruptedException;boolean tryLock();boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException;void unlock();Condition newCondition();}

如果查看JBoss AS7实现,您会注意到Lock&ReantrantLock在核心实现层中得到了广泛使用,例如:

  • 部署服务
  • EJB3实现(广泛使用)
  • 集群和会话管理
  • 内部缓存和数据结构(LRU,ConcurrentReferenceHashMap…)

现在,按照亨氏的观点,死锁解决方案#2可能非常有效,但也需要采取适当的措施,例如通过finally {}块释放所有持有的锁,否则您可以将死锁方案转换为活动锁 。

资源僵局

现在,让我们转到资源死锁场景。 我很高兴Heinz的实验室#3涵盖了这一点,因为根据我的经验,这是迄今为止您将看到的最常见的“死锁”场景,尤其是在开发和支持大型分布式Java EE生产系统时。

现在,让我们弄清事实。

  • 资源死锁不是真正的Java级死锁
  • 如果您遇到这些类型的死锁,那么JVM线程转储将不会神奇。 这意味着您需要做更多工作来分析和理解此问题作为起点。
  • 当您刚开始学习如何读取线程转储时,线程转储分析可能会特别令人困惑,因为对于Java级死锁,线程通常会显示为RUNNING状态还是BLOCKED状态。 现在,重要的是要记住线程状态对于这种类型的问题不是那么重要,例如RUNNING state!= Healthy state。
  • 分析方法与Java级别的死锁非常不同。 您必须创建多个线程转储快照,并确定每个快照之间的线程问题/等待模式。 您将能够看到线程没有移动,例如等待从池中获取资源的线程以及已经获取该资源并挂起的其他线程。
  • 线程转储分析不是这里重要的唯一数据点/事实。 您将需要收集其他事实,例如有关线程正在等待的资源,整体中间件或环境运行状况等的统计信息。所有这些事实的结合将使您能够得出根本原因以及解决策略的结论,或可能不涉及代码更改。

我将以更多的线程转储问题模式与您联系,但首先请确保您对JVM线程转储的基本原理感到满意。

结论

我希望您像我一样有机会回顾,运行和享受亨氏演讲中的实验室。 并发编程和故障排除可能会非常具有挑战性,但是我仍然建议您花一些时间来理解其中一些原则,因为我相信您会在不久的将来遇到某种情况,这将迫使您进行这种深入研究并掌握这些原则。技能。

参考: Java EE支持模式和Java教程博客中的JCG合作伙伴 Pierre-Hugues Charbonneau提供的Java死锁故障排除和解决方法 。

翻译自: https://www.javacodegeeks.com/2012/11/java-deadlock-troubleshooting-and-resolution.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java.util.scanner sc_关于Java的Scanner的问题,菜鸟求各大神解答

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼package leetcode;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.…

3. HTML中的容器标签

什么是容器标签&#xff1f;在HTML开发中我们常常会使用一类标签作为容器放置一些内容&#xff0c;我们把这类标签称之为容器标签&#xff0c;可以作为容器标签的包括列表标签、表格标签、框架标签、布局标签&#xff0c;在这里我们就来总结下这些内容。 列表标签 1 <!-- 无…

python自带sqlite库_Python标准库之sqlite3使用实例

Python自带一个轻量级的关系型数据库SQLite。这一数据库使用SQL语言。SQLite作为后端数据库&#xff0c;可以搭配Python建网站&#xff0c;或者制作有数据存储需求的工具。SQLite还在其它领域有广泛的应用&#xff0c;比如HTML5和移动端。Python标准库中的sqlite3提供该数据库的…

GitHub上Java的Bloom Bloom实现

布隆过滤器是集数据结构的一种 。 对于那些不了解的对象&#xff0c;“设置数据结构”仅包含一个主要方法。 它仅用于确定特定元素是否包含在一组元素中。 大多数数据结构&#xff08;例如Hash Map &#xff0c; Linked List或Array &#xff09;都可以相当轻松地创建此函数。 …

Hibernate(十五):QBC检索、本地SQL检索和HQL删除

QBC检索QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象&#xff0c;这种API封装了SQL语句的动态拼装&#xff0c;对查询提供了更加面向对象的功能接口。 1&#xff09;通过Critera实现具有条件的查询 1 Test2 public void testCriteria00() {3 …

java 创建连接池失败_java-Presto JDBC连接池创建错误“不支持禁用...

我正在尝试使用Spring-JDBC连接到Presto,并且我正在使用Hikari CP作为数据源.这是我的配置&#xff1a;Beanpublic DataSource myDataSource() {HikariDataSource hikariDataSource new HikariDataSource();hikariDataSource.setDriverClassName("com.facebook.presto.jd…

ni软件管理器_NI 技术支持丨我的 NI 硬件设备不能被识别,怎么办?Windows

这篇指南可以帮助您解决在您的 Windows 系统上无法识别您的 NI 硬件有关的问题。症状包括以下几种情况&#xff1a;连接至 USB 端口时&#xff0c;硬件上的 LED 灯不亮/不闪烁。连接至 USB 后已连接设备的 LED 灯持续闪烁。仅限音频接口&#xff1a;该设备在音频应用程序或 Win…

环境搭建相关

1.检测jre运行环境 java -version 没有的话 按照提示安装 default-jre 够用 http://www.linuxidc.com/Linux/2016-11/136958.htm 否则按照上面处理 2.pycharm下载 https://www.jetbrains.com/pycharm/download/ 选择下载一个linux的 3.下载crackjar http://idea.lanyus.com/jar…

在Java应用程序中使用密码学

这篇文章描述了如何使用Java密码体系结构 &#xff08;JCA&#xff09;&#xff0c;该体系结构使您可以在应用程序中使用密码服务。 Java密码体系结构服务 JCA提供了许多加密服务&#xff0c;例如消息摘要和签名 。 这些服务可以通过特定于服务的API来访问&#xff0c;例如Me…

CSS学习笔记-04 a标签-导航练习

个人练习&#xff0c;各位大神勿笑 。。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&qu…

AngularJs简介

AngualrJs是一个javascript框架&#xff0c;它通过<script>标签加到HTML页面中。 Angular通过指令拓展了HTML&#xff0c;且通过表达式绑定数据到HTML。 Angular是一个javascript框架 Angular是一个javascript框架。它是一个以javascript编写的库。 Angular是以一个javas…

java怎样访问servlet_如何访问URL并从java servlet获取响应?

你需要做这样的事情import java.io.*;import java.net.URL;import java.net.URLConnection;import javax.servlet.http.*;import javax.servlet.*;public class URLServlet extends HttpServlet {public void doGet(HttpServletRequest req, HttpServletResponse res)throws Se…

深度学习loss值变为0_利用TensorFlow2.0为胆固醇、血脂、血压数据构建时序深度学习模型(python源代码)...

背景数据描述胆固醇、高血脂、高血压是压在广大中年男性头上的三座大山&#xff0c;如何有效的监控他们&#xff0c;做到早发现、早预防、早治疗尤为关键&#xff0c;趁着这个假期我就利用TF2.0构建了一套时序预测模型&#xff0c;一来是可以帮我预发疾病&#xff0c;二来也可以…

在Spring MVC Web应用程序中使用reCaptcha

CAPTCHA是一种程序&#xff0c;可以生成人类可以通过的测试并对其进行评分&#xff0c;而计算机程序“ 不能 ”通过。 所采取的策略之一是向用户显示具有扭曲文本的图像&#xff0c;并且用户应在输入区域中书写文本。 如果显示的文字与用户输入的文字相同&#xff0c;则我们可以…

洛谷 P1757 通天之分组背包

P1757 通天之分组背包 题目背景 直达通天路小A历险记第二篇 题目描述 自01背包问世之后&#xff0c;小A对此深感兴趣。一天&#xff0c;小A去远游&#xff0c;却发现他的背包不同于01背包&#xff0c;他的物品大致可分为k组&#xff0c;每组中的物品相互冲突&#xff0c;现在&a…

课时109.外边距合并现象(掌握)

我们先写一个案例&#xff0c;通过案例来了解 它们之间的水平距离就是两个间距的和 我们看完水平再来看垂直方向 在默认布局的垂直方向上&#xff0c;默认情况下外边距是不会叠加的&#xff0c;会出现合并现象&#xff0c;谁的外边距比较大就听谁的 本文转载于:猿2048➜https:…

纯 CSS实现三角形

最近项目上做评论回复&#xff0c;设计师提高交互性特意设计了小三角&#xff0c;如下&#xff1a; 下面介绍一下实现效果的css方法&#xff1a; 1.border 通过设置上下左右border宽度来实现。 首先查看一下全部设置的效果&#xff1a; <style>   .triangle{     w…

python access_Python3 os.access() 方法

Python3 os.access() 方法概述os.access() 方法使用当前的uid/gid尝试访问路径。大部分操作使用有效的 uid/gid, 因此运行环境可以在 suid/sgid 环境尝试。语法access()方法语法格式如下&#xff1a;os.access(path, mode);参数path -- 要用来检测是否有访问权限的路径。mode -…

小米的java待遇怎么样_【Java工资】小米2021年Java工资待遇-看准网

已经不是面试官迟到的问题了&#xff0c;是约好了面试时间&#xff0c;结果彻底没有然后了&#xff0c;这种言而无信我头一回见。小米运营部门令人困惑的工作作风&#xff0c;简单总结一句就是&#xff1a;敷衍不走心&#xff0c;面试规则内部都不统一。两次面小米&#xff0c;…

Spring MVC表单验证(带批注)

这篇文章提供了一个简单HTML表单验证示例。 它基于带有注释的Spring MVC示例。 该代码可在GitHub的Spring-MVC-Form-Validation目录中找到。 数据 在此示例中&#xff0c;我们将使用bean和JSR303验证批注&#xff1a; public class MyUser {NotNullSize(min1,max20)private …