Java中死锁的原理实战分析

 更新时间:2019年08月27日 09:56:47   作者:cakincqm  
这篇文章主要介绍了Java中死锁的原理,结合具体案例形式分析了java死锁形成的相关原理,需要的朋友可以参考下

本文实例讲述了Java中死锁的原理。分享给大家供大家参考,具体如下:

一 点睛

当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚拟机没有监测、也没有采用措施来处理死锁情况,所以多线程编程时应该采取措施避免死锁的出现。

一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。

二 代码

class A
{
   public synchronized void foo( B b )
   {
      System.out.println("当前线程名: " + Thread.currentThread().getName()
        + " 进入了A实例的foo()方法" );   // ①
      try
      {
        Thread.sleep(200);
      }
      catch (InterruptedException ex)
      {
        ex.printStackTrace();
      }
      System.out.println("当前线程名: " + Thread.currentThread().getName()
        + " 企图调用B实例的last()方法");  // ③
      b.last();
   }
   public synchronized void last()
   {
      System.out.println("进入了A类的last()方法内部");
   }
}
class B
{
   public synchronized void bar( A a )
   {
      System.out.println("当前线程名: " + Thread.currentThread().getName()
        + " 进入了B实例的bar()方法" );  // ②
      try
      {
        Thread.sleep(200);
      }
      catch (InterruptedException ex)
      {
        ex.printStackTrace();
      }
      System.out.println("当前线程名: " + Thread.currentThread().getName()
        + " 企图调用A实例的last()方法"); // ④
      a.last();
   }
   public synchronized void last()
   {
      System.out.println("进入了B类的last()方法内部");
   }
}
public class DeadLock implements Runnable
{
   A a = new A();
   B b = new B();
   public void init()
   {
      Thread.currentThread().setName("主线程");
      // 调用a对象的foo方法
      a.foo(b);
      System.out.println("进入了主线程之后");
   }
   public void run()
   {
      Thread.currentThread().setName("副线程");
      // 调用b对象的bar方法
      b.bar(a);
      System.out.println("进入了副线程之后");
   }
   public static void main(String[] args)
   {
      DeadLock dl = new DeadLock();
      // 以dl为target启动新线程
      new Thread(dl).start();
      // 调用init()方法
      dl.init();
   }
}

三 运行结果

当前线程名: 主线程 进入了A实例的foo()方法
当前线程名: 副线程 进入了B实例的bar()方法
当前线程名: 主线程 企图调用B实例的last()方法
当前线程名: 副线程 企图调用A实例的last()方法

四 说明

从运行结果来看,程序无法向下执行,也不会抛出任何异常,就一直“僵持”者。

上面代码中的A对象和B对象的方法都是同步方法,也就是A对象和B对象都是同步锁。

程序中有两个线程执行,一个线程的线程执行体是DeadLock类的run()方法,另外一个是DeadLock的init()方法(主线程调用init()方法)。其中run()方法让B对象调用bar()方法,而init()方法让A对象调用foo()方法。

程序运行的流程如下:

  • 1 init()方法先执行,调用A对象的foo()方法,进入foo()方法之前,该线程对A对象加锁,进入foo()方法后,打印一下,然后暂停执行200ms
  • 2 CPU切换到另外一个线程,让B对象执行bar方法,进入bar()方法之前,该线程对B对象加锁,进入bar()方法后,打印一下,然后暂停执行200ms
  • 3 主线程先醒过来,继续向下执行,当调用B对象的last方法时,会被阻塞,因为此时必须对B对象进行加锁,但此时副线程正保持B对象的锁,所以此时主线程会一直等待。
  • 4 副线程会醒过来,会继续往下执行,当调用A对象的last方法时,会被阻塞,因为此时必须对A对象加锁,但此时主线程正保持A对象的锁,所以此时副线程会一直等待。
  • 5 两个线程互相等待对方先释放,所以出现了死锁。

更多java相关内容感兴趣的读者可查看本站专题:《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

相关文章

  • java计算自幂数和水仙花数

    java计算自幂数和水仙花数

    对于一个正整数而言,长度是n,如果它的各位上的数字的n次方之和正好等于它本身,那么我们称这样的数为自幂数,下面使用JAVA实现这个方法
    2014-03-03
  • window版 IntelliJ IDEA 快捷键图文教程

    window版 IntelliJ IDEA 快捷键图文教程

    本文通过图文并茂的形式给大家介绍了window版 IntelliJ IDEA 快捷键的操作方法,需要的朋友参考下吧
    2018-02-02
  • spring是如何解析xml配置文件中的占位符

    spring是如何解析xml配置文件中的占位符

    这篇文章主要介绍了spring是如何解析xml配置文件中的占位符,帮助大家更好的理解和使用spring框架,感兴趣的朋友可以了解下
    2020-11-11
  • SpringBoot 防御 CSRF 攻击的流程及原理解析

    SpringBoot 防御 CSRF 攻击的流程及原理解析

    CSRF是一种非常常见的Web攻击方式,其实是很好防御的,但是由于经常被很多开发者忽略,进而导致很多网站实际上都存在 CSRF 攻击的安全隐患,这篇文章主要介绍了SpringBoot 如何防御 CSRF 攻击,需要的朋友可以参考下
    2023-05-05
  • IDEA入门级使用教程你居然还在用eclipse?

    IDEA入门级使用教程你居然还在用eclipse?

    上个月,idea的使用量超越eclipse的消息席卷了整个IT界,idea到底好在哪里呢?下面小编通过本文给大家详细介绍下IDEA入门级使用教程,非常详细,感兴趣的朋友一起看看吧
    2020-10-10
  • SpringBoot基于Redis实现token的在线续期的实践

    SpringBoot基于Redis实现token的在线续期的实践

    本文主要介绍了使用Redis实现JWT令牌在线续期的方案,通过在线续期token,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • ChatGPT在IDEA中使用的详细过程

    ChatGPT在IDEA中使用的详细过程

    这篇文章主要介绍了ChatGPT在IDEA中使用的详细过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-02-02
  • 如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    这篇文章主要介绍了如何在Spring Boot应用中优雅的使用Date和LocalDateTime,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • springboot中使用雪花算法生成雪花ID

    springboot中使用雪花算法生成雪花ID

    本文主要介绍了springboot中使用雪花算法生成雪花ID,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • JAVA验证码工具实例代码

    JAVA验证码工具实例代码

    这篇文章主要介绍了JAVA验证码工具实例代码,需要的朋友可以参考下
    2018-03-03

最新评论