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月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
335 4
|
1月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
190 0
|
1月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
234 115
|
1月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
171 98
|
1月前
|
Java 编译器 API
java最新版和java8的区别,用代码展示
java最新版和java8的区别,用代码展示
242 43
|
1月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
146 6
|
1月前
|
安全 前端开发 Java
从反射到方法句柄:深入探索Java动态编程的终极解决方案
从反射到方法句柄,Java 动态编程不断演进。方法句柄以强类型、低开销、易优化的特性,解决反射性能差、类型弱、安全性低等问题,结合 `invokedynamic` 成为支撑 Lambda 与动态语言的终极方案。
145 0
|
1月前
|
安全 Java 容器
告别空指针噩梦:Optional让Java代码更优雅
告别空指针噩梦:Optional让Java代码更优雅
358 94
|
1月前
|
安全 Java 容器
告别繁琐判空:Optional让你的Java代码更优雅
告别繁琐判空:Optional让你的Java代码更优雅
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
143 1
下一篇
oss云网关配置