如何避免Java中的死锁?是流行的Java面试问题之一,也是多线程的流行话题之一。尽管问题看起来很简单,但是一旦深入,大多数Java开发人员就会陷入困境。

面试问题以“什么是死锁?”当两个或多个线程正在等待彼此释放所需资源(锁定)并陷入无限时间的阻塞时,这种情况称为死锁,它只会在多任务或多线程的情况下发生。

如何检测Java中的死锁?

虽然这可能有很多答案,但我的版本是,如果我看到嵌套的同步块,或者从其他同步方法调用一个同步方法,或者试图在不同的对象上获得锁,那么如果开发人员不是非常小心,就很可能出现死锁。

另一种方法是在运行应用程序时发现线程被锁定,尝试使用线程转储,在Linux中可以通过命令“kill -3”来实现,这将打印应用程序日志文件中所有线程的状态,就可以看到哪个线程被锁定在哪个对象上。

也可以使用fastthread等工具分析线程转储,上传你的线程转储并分析它。

另一种方法是使用jConsole/VisualVM,它将准确地显示哪些线程被锁定,以及在哪个对象上。

编写一个会导致死锁的Java程序

一旦回答了前面的问题,他们可能会要求你编写导致Java死锁的代码

这是我的一个版本

/**

* Java程序通过强制循环等待来创建死锁

*

* @author WINDOWS 8

*

*/

public class DeadLockDemo {

/*

* T此方法请求两个锁,首先是String,然后是Integer

*/

public void method1() {

synchronized (String.class) {

System.out.println("Aquired lock onString.classobject");

synchronized (Integer.class) {

System.out.println("Aquired lock on Integer.class object");

}

}

}

/* * 此方法也请求相同的两个锁

* 顺序相反,先整型,然后是字符串

* 如果一个线程持有字符串锁,则会产生潜在的死锁

* 另一个持有整数锁,它们会一直等待对方

*/

public void method2() {

synchronized (Integer.class) {

System.out.println("Aquired lock on Integer.classobject");

synchronized (String.class) {

System.out.println("Aquired lock on String.class object");

}

}

}

}

如果method1()和method2()都将被两个或多个线程调用,那么死锁的可能性很大,如果线程1在执行method1()时获取Sting对象上的锁,而线程2在执行method2()时获取Integer对象上的锁,那么线程2将等待对方释放Integer和String上的锁以继续执行,而这永远不会发生

此图准确演示了我们的程序,其中一个线程持有一个对象的锁并等待其他线程持有的其他对象锁。

这个图展示了我们的这个程序,一个线程持有一个对象的锁,等待另一个线程持有的其他对象锁。

你可以看到线程1想要对线程2持有的对象2的锁定,而线程2想要对线程1持有的对象1进行锁定。由于没有线程愿意放弃,所以存在死锁并且Java程序卡住了。

如何避免Java中的死锁

现在面试官来到最后一部分,这是我认为最重要的部分之一; 你如何修复代码中的死锁?或者如何避免Java中的死锁?

如果仔细查看了上面的代码,那么你可能已经发现死锁的真正原因不是多线程,而是它们请求锁定的方式,如果提供有序访问,则问题将得到解决。

这是我的固定版本,它避免了由于没有抢占的无效循环等待导致的死锁,这是需要死锁的四个条件之一。

public class DeadLockFixed {

/**

* 两种方法现在都以相同的顺序请求锁定,首先是Integer,然后是String。

* 也可以完成反向,例如第一个String然后是Integer

* 两者都会解决问题,只要两种方法都请求锁定

* 按照一致的顺序

*/

public void method1() {

synchronized (Integer.class) {

System.out.println("Aquired lock on Integer.class object");

synchronized (String.class) {

System.out.println("Aquired lock on String.class object");

}

}

}

public void method2() {

synchronized (Integer.class) {

System.out.println("Aquired lock on Integer.class object");

synchronized (String.class) {

System.out.println("Aquired lock on String.class object");

}

}

}

}

现在不存在任何死锁,因为两个方法都以相同的顺序访问Integer和String类文字的锁。因此,如果线程A获取对Integer对象的锁定,则线程B将不会继续,直到线程A释放整数锁定,同样,即使线程B保持字符串锁定,线程A也不会被阻止,因为现在线程B不会期望线程A释放整数锁定继续进行。

java线程如何避免死锁_Java面试问题,如何避免Java线程中的死锁?相关推荐

  1. Java分析MySQL的数据结构_Java面试解析总结:Java+Redis+数据库+算法与数据结构+分布式...

    金九银十即将到来,给大家整理了今年来最经典的面试真题1000+道,每个题目都有详细的解答,收集了java基础.RabbitMQ,微服务.MySQL数据库.Java并发.JVM,Redis.设计模式,S ...

  2. java程序给输出汉字_java面试题目编写一个java程序,实现拼音转成对应汉字功能。...

    Map> map=new HashMap>(); /** * 录入a */ List as=new ArrayList(); as.add("啊"); as.add(& ...

  3. 2020年Java面试题及答案_Java面试宝典_Java笔试题(持续更新中)

    推荐面试视频教程 2019年最新Java互联网大厂面试精粹 前言 前言: 少年易老学难成,一寸光阴不可轻.未觉池塘春草梦,阶前梧叶已秋声 .-朱熹<劝学诗> 勤奋才是改变你命运的唯一捷径. ...

  4. 线程 sleep 取消_Java面试集锦:25道线程类相关面试题与答案(下)

    26. 并发编程三要素? 1)原子性 原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行. 2)可见性 可见性指多个线程操作一个共享变量时,其中一个线程对 ...

  5. 面试java常问的问题_java面试官常问的问题

    http://www.ahsrst.cn中多线程同步是什么? 在多线程程序下,同步能控制对共享资源的访问.如果没有同步,当一个 Java 线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变 ...

  6. java 多态判断非空_Java 面试知识点解析基础知识

    文本公众号来源: 我没有三颗心脏作者: 我没有三颗心脏 (一)Java 基础知识点 1)面向对象的特性有哪些? 答:封装.继承和多态(应要多算一个那就是抽象) 封装是指将对象的实现细节隐藏起来,然后通 ...

  7. java中的servlet是线程安全的嘛_Java面试题:Servlet是线程安全的吗?(转)

    Servlet不是线程安全的. 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时 ...

  8. list集合排序_Java面试第七部分 Java的集合

    7.1. HashMap排序题 已知一个 HashMap<Integer,User>集合, User 有 name(String)和 age(int)属性.请写一个方法实现对HashMap ...

  9. 面试官:怎么解决MySQL中的死锁问题?

    咱们使用 MySQL 大概率上都会遇到死锁问题,这实在是个令人非常头痛的问题.本文将会对死锁进行相应介绍,对常见的死锁案例进行相关分析与探讨,以及如何去尽可能避免死锁给出一些建议. 话不多说,开整! ...

最新文章

  1. 第七周项目二-友元类
  2. Linux_系统进程管理
  3. 基于自然语言的软件工程和程序设计(下)
  4. linux apache守护进程,Linux基础命令---httpd守护进程
  5. 党在心中(turtle画图)
  6. C语言学习笔记--函数与指针
  7. 字符串处理 - DataFrame文本数据的量化 - Python代码
  8. linux中将 home目录备份成,6种优化Linux系统备份的应用与技巧
  9. 从Oracle到PostgreSQL:最全控制文件
  10. 处理机和处理器的区别
  11. Axure 9 实战案例,动态面板的应用 3,京东的拖动拼图登录验证
  12. 阿里云网盘内测_叫板百度网盘?阿里云网盘内测中,下载速度是亮点
  13. DIV 半透明层、 CSS实现网页 背景半透明
  14. js 校验是否合法的中国身份证
  15. 工作日记---android lockscreen.java 在lock状态下显示charing和alarm
  16. ar8161网卡 linux,解决AR8161网卡驱动的方法
  17. create方法 eslint关闭_react create-react-app使用less 及关闭eslint
  18. 【Docker】error pulling image configuration: download failed after attempts=6: dial tc
  19. Linux指令(二)
  20. linux下批量改文件名命令,Linux 批量更改文件名命令

热门文章

  1. 关于a标签不能调用js方法的小细节,你注意到了么?
  2. SpringMVC原理及非注解配置详解
  3. vue实战学习第二天
  4. Flume之核心架构深入解析
  5. PHP上传文件大小限制的问题(转)
  6. char、varchar、nchar、nvarchar的区别
  7. 配置快捷键让Total Commander跳转到某个目录
  8. Flash 杂志《summer tree》 第六期发布
  9. 你知道用git打补丁吗?
  10. CoInitialize\CoCreateGuid\CoCreateInstance