java并发编程:死锁代码示例

简介: 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

死锁概念:


死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

-------- 百度百科


死锁的规范定义:


集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。

-------- 百度百科


代码示例:


/**
 * java死锁示例
 */
public class DeadLock {
    private static final Object OBJECT1 = new Object();
    private static final Object OBJECT2 = new Object();
    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (OBJECT1) {
                try {
                    // cpu执行太快,利用休眠触发死锁
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (OBJECT2) {
                    System.out.println("OBJECT1获取到了OBJECT2的锁!");
                }
            }
        }).start();
        new Thread(() -> {
            synchronized (OBJECT2) {
                synchronized (OBJECT1) {
                    System.out.println("OBJECT2获取到了OBJECT1的锁!");
                }
            }
        }).start();
    }
}


查看死锁的方法:

方法一:jps + jstack


首先用jps查看进程id


Terminal:$ jps
1488 Launcher
1489 DeadLock
1490 Jps
1255 


再用jstack 1489(进程id) 查看堆栈信息


Terminal:$ jstack 1489
Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007fdf0e80ed68 (object 0x000000076ac28c70, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007fdf0e8100a8 (object 0x000000076ac28c80, a java.lang.Object),
  which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.farstars.demo.DeadLock.lambda$main$1(DeadLock.java:29)
        - waiting to lock <0x000000076ac28c70> (a java.lang.Object)
        - locked <0x000000076ac28c80> (a java.lang.Object)
        at com.farstars.demo.DeadLock$$Lambda$2/2129789493.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"Thread-0":
        at com.farstars.demo.DeadLock.lambda$main$0(DeadLock.java:21)
        - waiting to lock <0x000000076ac28c80> (a java.lang.Object)
        - locked <0x000000076ac28c70> (a java.lang.Object)
        at com.farstars.demo.DeadLock$$Lambda$1/1607521710.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.


从上述堆栈信息中可以很明显的看到发生了死锁现象。


方法二:jconsole


命令行直接敲jconsole命令,使用自带的控制台查看死锁情况


20190526182247629.png


这里选择本地进程中的死锁类即可,然后点击连接。


20190526182348625.png


然后再点击线程这一栏,点击下方检测死锁。


20190526182553543.png


这里也可以清晰的看到进程的死锁情况,Thread-0和Thread-1分别持有对方的锁。


总结:


非常简单的死锁代码示例,同时利用java自带的工具帮助我们确认是否发生死锁现象。

目录
相关文章
|
1天前
|
前端开发 IDE Java
"揭秘前端转Java的秘径:SpringBoot Web极速入门,掌握分层解耦艺术,让你的后端代码飞起来,你敢来挑战吗?"
【8月更文挑战第19天】面向前端开发者介绍Spring Boot后端开发,通过简化Spring应用搭建,快速实现Web应用。本文以创建“Hello World”应用为例,展示项目基本结构与运行方式。进而深入探讨三层架构(Controller、Service、DAO)下的分层解耦概念,通过员工信息管理示例,演示各层如何协作及依赖注入的使用,以此提升代码灵活性与可维护性。
|
1天前
|
设计模式 算法 安全
Java编程中的设计模式:提升代码的可维护性和扩展性
【8月更文挑战第19天】在软件开发的世界里,设计模式是解决常见问题的一种优雅方式。本文将深入探讨Java编程语言中常用的几种设计模式,并解释如何通过这些模式来提高代码的可维护性和扩展性。文章不涉及具体的代码实现,而是侧重于理论和实践相结合的方式,为读者提供一种思考和改善现有项目的新视角。
|
1天前
|
设计模式 Java
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
文章提供了一份常用设计模式的全面介绍,包括创建型模式、结构型模式和行为型模式。每种设计模式都有详细的概念讲解、案例说明、代码实例以及运行截图。作者通过这些模式的介绍,旨在帮助读者更好地理解源码、编写更优雅的代码,并进行系统重构。同时,文章还提供了GitHub上的源码地址,方便读者直接访问和学习。
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
|
1天前
|
安全 Java 测试技术
常见 Java 代码缺陷及规避方式
在日常开发过程中,我们会碰到各种各样的代码缺陷或者 Bug,比如 NPE、 线程安全问题、异常处理等。这篇文章总结了一些常见的问题及应对方案,希望能帮助到大家。
|
1天前
|
安全 Java 程序员
阿里开发手册 嵩山版-编程规约 (四)OOP规约-Java程序员必看知识点!!!
《阿里开发手册 嵩山版》的OOP规约部分强调了面向对象编程的最佳实践,包括正确使用静态方法、覆写方法的注解、可变参数的使用、接口的稳定性、equals和compareTo方法的使用、BigDecimal的正确比较、包装类与基本数据类型选择、POJO类的属性和方法设计等,以提升代码的质量和维护性。
11 0
|
1天前
|
Java 程序员
"Java程序员必备秘籍:Lambda表达式如何让你的代码瘦身90%?揭秘简化编程的终极奥秘!"
【8月更文挑战第19天】Java持续进化,Lambda表达式自Java 8起赋予其新活力。它简化代码,使编程更愉悦。以前,简单功能需冗长代码,如列表排序要用匿名内部类实现`Comparator`。现在一行Lambda足矣。Lambda如`(参数) -&gt; {表达式}`,支持零或多参数。
|
2月前
|
Java C++
关于《Java并发编程之线程池十八问》的补充内容
【6月更文挑战第6天】关于《Java并发编程之线程池十八问》的补充内容
39 5
|
25天前
|
安全 Java 开发者
Java中的并发编程:深入理解线程池
在Java的并发编程中,线程池是管理资源和任务执行的核心。本文将揭示线程池的内部机制,探讨如何高效利用这一工具来优化程序的性能与响应速度。通过具体案例分析,我们将学习如何根据不同的应用场景选择合适的线程池类型及其参数配置,以及如何避免常见的并发陷阱。
29 1
|
29天前
|
监控 Java
Java并发编程:深入理解线程池
在Java并发编程领域,线程池是提升应用性能和资源管理效率的关键工具。本文将深入探讨线程池的工作原理、核心参数配置以及使用场景,通过具体案例展示如何有效利用线程池优化多线程应用的性能。
|
12天前
|
Java 数据库
Java中的并发编程:深入理解线程池
在Java的并发编程领域,线程池是提升性能和资源管理的关键工具。本文将通过具体实例和数据,探讨线程池的内部机制、优势以及如何在实际应用中有效利用线程池,同时提出一个开放性问题,引发读者对于未来线程池优化方向的思考。
31 0