java中线程死锁及避免

如何避免Java中的死锁? 是Java面试中最受欢迎的问题之一,也是本季多线程的风格,主要是在高层提出,并带有很多后续问题。 尽管问题看起来很基础,但是一旦您开始深入研究,大多数Java开发人员就会陷入困境。

面试问题始于“什么是僵局?”

当两个或多个线程正在等待彼此释放所需的资源(锁定)并无限期陷入困境时,答案很简单,这种情况称为死锁。 它只会在多任务 或多线程的情况下发生。

如何在Java中检测死锁?

尽管可能会有很多答案,但我的版本是:如果我看到一个嵌套的同步块或从另一个调用一个同步方法,或者试图锁定另一个对象,那么我将看一下代码,那么很有可能发生死锁如果开发人员不是很谨慎。

另一种方法是在运行应用程序时实际上陷入僵局时找到它,尝试进行线程转储,在Linux中,您可以通过“ kill -3”命令执行此操作,这将在应用程序日志文件中打印所有线程的状态您可以看到哪个线程锁定在哪个对象上。

您可以使用fastthread.io之类的工具来分析该线程转储,该工具允许您上载线程转储并进行分析。

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

编写Java程序会导致死锁?

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

这是我的版本之一:

/*** Java program to create a deadlock by imposing circular wait.* * @author WINDOWS 8**/
public class DeadLockDemo {/** This method request two locks, first String and then Integer*/public void method1() {synchronized (String.class) {System.out.println("Aquired lock on String.class object");synchronized (Integer.class) {System.out.println("Aquired lock on Integer.class object");}}}/** This method also requests same two lock but in exactly* Opposite order i.e. first Integer and then String. * This creates potential deadlock, if one thread holds String lock* and other holds Integer lock and they wait for each other, forever.*/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");}}}
}

如果method1()和method2()都将被两个或多个线程调用,则死锁的可能性很大,因为如果线程1在执行method1()时获得Sting对象的锁,而线程2在执行method2时获得Integer对象的锁, () 都将互相等待,以释放对Integer的锁定 ,而String继续进行下去,这将永远不会发生。

该图准确地演示了我们的程序,其中一个线程在一个对象上持有一个锁,然后等待另一线程持有的其他对象锁。

您可以看到线程1想要锁定对象2的锁,该对象2由线程2持有,而线程2想要锁定对象1的锁,该对象1由线程1持有。由于没有线程愿意放弃,因此存在死锁,并且线程2 Java程序被卡住。

如何避免Java中的死锁?

现在,面试官进入最后一部分,在我看来,这是最重要的部分。
您如何解决代码中的死锁?如何避免Java中的死锁?

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

这是我的固定版本,它通过无效循环循环等待来避免死锁, 而没有抢占 ,这是需要死锁的四个条件之一。

public class DeadLockFixed {/*** Both method are now requesting lock in same order, first Integer and then String.* You could have also done reverse e.g. first String and then Integer,* both will solve the problem, as long as both method are requesting lock* in consistent order.*/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对象的锁定,则直到线程A释放Integer锁定后,线程B才会继续进行,即使线程B持有字符串锁,线程A也不会被阻塞,因为现在线程B不会期望线程A释放整数锁可继续进行。

感谢您阅读本文。 如果您喜欢这篇文章,请与您的朋友和同事分享。 如果您有任何疑问或反馈,请留言。

翻译自: https://www.javacodegeeks.com/2018/08/avoid-deadlock-java-threads.html

java中线程死锁及避免

java中线程死锁及避免_如何避免Java线程中的死锁?相关推荐

  1. java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题

    先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...

  2. 简述java 线程四个状态_面四个选项中,哪些是线程进入阻塞状态的原因?_学小易找答案...

    [简答题]通过继承 Thread 类的方式创建两个线程,在 Thread 构造方法中指定线程的名字,并将这两个线程的名字打印出来. [论述题]请运用所学原理解释,为什么在孩子成长的过程中,家长要不断地 ...

  3. java中关于线程的状态属性_深入理解Java多线程与并发框(第①篇)——线程的状态...

    ![](http://img.blog.itpub.net/blog/2020/03/20/5d189a73e1147f37.png?x-oss-process=style/bb) **1. 新建状态 ...

  4. java中的标识符和关键字_浅谈java中的标识符、修饰符和关键字

    合法标识符 Java语言中,对于变量,常量,函数,语句块均有名字,我们统统称之为Java标识符.标识符是用来给类.对象.方法.变量.接口和自定义数据类型命名的. 组成:Java标识符由数字,字母和下划 ...

  5. java中线程调度遵循的原则_深入理解Java多线程核心知识:跳槽面试必备

    多线程相对于其他 Java 知识点来讲,有一定的学习门槛,并且了解起来比较费劲.在平时工作中如若使用不当会出现数据错乱.执行效率低(还不如单线程去运行)或者死锁程序挂掉等等问题,所以掌握了解多线程至关 ...

  6. java线程间通信管道_通过管道进行线程间通信

    管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据.一个线程发送数据到输出管道,另一个线程从输入管道中读数据.通过管道,实现不同线程间的通信,而无须借助类似共享变量.临时文件之 ...

  7. java线程池深入讲解_死磕 java线程系列之线程池深入解析——生命周期

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 上一章我们一起重温了下线程的 ...

  8. java中常量final的用法_详解Java中final的用法

    本文主要介绍了Java中final的使用方法,final是java的关键字,本文就详细说明一下它的使用方法,需要的朋友可以参考下 概念 final 具有"不可改变的"的含义,可以修 ...

  9. 设置线程当天十二点执行_这份JAVA多线程笔记真的是细节满满,几乎全是你工作能用到的干货...

    前言 1:发挥多核CPU的优势(充分利用cpu资源) 如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%.单核CPU上所谓的"多线程"那是假的多线程 ...

最新文章

  1. 【jQuery】jQuery知识点梳理(持续更新)
  2. CTO 说了,如果发现谁用 kill -9 关闭程序就开除
  3. Sublime Text 2/3 配置文件详解
  4. 将“softmax+交叉熵”推广到多标签分类问题
  5. 60.Java 代码编译和执行的整个过程
  6. PLSQL_day01
  7. PHP上传文件到七牛云和阿里云
  8. 你为什么选择计算机这个专业英语,怎样选择计算机专业,英文作文:为什么选择计算机作为你的专业...
  9. python rsa加密解密 字符串_python_rsa加密解密
  10. OpenGL与gl glu glut freeglut glew glfw封装库关系(十五)
  11. vs2010设置 行号显示
  12. 【Java】java插件化开发
  13. 数据oracle的等保三级测评,等级保护测评三级详解测评要求项测评方法及测评步骤...
  14. ajax请求406,Ajax请求返回(406不可接受)
  15. 间接寻址储存的线性表—基本操作实现
  16. GB/T 20281-2020实施两周年,美创数据库防火墙的标准实践
  17. oracle中删除级联方法,Oracle 外键级联删除
  18. Ubuntu在线安装NFS服务
  19. Python:画三角形
  20. shell字符串,字符数组,遍历

热门文章

  1. 第1节 连通性强连通、割点和桥 例题
  2. [APIO2014] 序列分割(斜率优化dp)
  3. [APIO2016] 划艇(dp + 组合数 + 前缀和优化)
  4. 判断整除(opj)(动态规划)
  5. P3157-[CQOI2011]动态逆序对【CDQ分治,树状数组】
  6. jzoj1247-队列变换【字符串hash,二分】
  7. CF741D-Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths【树上启发式合并】
  8. P1967,ssl2267-货车运输【树上倍增LCA,最小生成树变形kruskal】
  9. ssl2331OJ1373-鱼塘钓鱼 之1【纯贪心】
  10. 星座图(2020特长生 T4)