• 重新认识Java中的死锁问题


    一、定义

    多个进程因抢夺系统资源而产生相互等待的现象。

    二、场景模拟

    1. package com.gui.practise.thread.deadlock;
    2. public class DeadLock {
    3. private final Object resource1 = new Object();//资源 1
    4. private final Object resource2 = new Object();//资源 2
    5. public void leftRight() {
    6. synchronized (resource1) {
    7. System.out.println(Thread.currentThread() + "get resource1");
    8. try {
    9. Thread.sleep(1000);
    10. } catch (InterruptedException e) {
    11. e.printStackTrace();
    12. }
    13. System.out.println(Thread.currentThread() + "waiting get resource2");
    14. synchronized (resource2) {
    15. System.out.println(Thread.currentThread() + "get resource2");
    16. }
    17. }
    18. }
    19. public void rightLeft() {
    20. synchronized (resource2) {
    21. System.out.println(Thread.currentThread() + "get resource2");
    22. try {
    23. Thread.sleep(1000);
    24. } catch (InterruptedException e) {
    25. e.printStackTrace();
    26. }
    27. System.out.println(Thread.currentThread() + "waiting get resource1");
    28. synchronized (resource1) {
    29. System.out.println(Thread.currentThread() + "get resource1");
    30. }
    31. }
    32. }
    33. }
    1. package com.gui.practise.thread.deadlock;
    2. public class DeadLockTest {
    3. public static void main(String[] args) {
    4. DeadLock dl = new DeadLock();
    5. new Thread(() -> {
    6. dl.leftRight();
    7. }, "线程 1").start();
    8. new Thread(() -> {
    9. dl.rightLeft();
    10. }, "线程 2").start();
    11. }
    12. }

    三、死锁检测

    Java自带工具检测死锁

    第一步:jps找到对应进程

    第二步:jstack查看对应堆栈信息

    阿里巴巴开源的java诊断工具arthas

    下载地址:https://github.com/alibaba/arthas/releases

    四、特点&预防&解除

    特点
    • 互斥(多个线程不能同时使用一个资源)
    • 不可剥夺(资源请求者不能强制从资源占有者手中抢夺资源,资源只能由占有者主动释放)
    • 持有并等待(当资源请求者在请求其他资源的同时保持对原有资源的占有)
    • 环路(多个线程存在环路的锁依赖关系而永远等待下去)
    预防
    • 能无锁开发就无锁开发
    • 如果确实需要使用锁,核心原则:资源有序分配法(各个线程总是以相同的顺序申请自己想要的资源)
    • 合理的锁顺序
    • 更小的锁范围
    • 使用定时锁,比如Lock类中的tryLock方法
    解除
    • 直接重启服务,如果代码未进行修复,问题还会出现
    • 使用定时锁方案,Lock的tryLock方法

    五、使用资源有序分配法解除场景模拟中的死锁问题

    1. package com.gui.practise.thread.deadlock;
    2. public class DeadLock {
    3. private final Object resource1 = new Object();//资源 1
    4. private final Object resource2 = new Object();//资源 2
    5. public void leftRight() {
    6. synchronized (resource1) {
    7. System.out.println(Thread.currentThread() + "get resource1");
    8. try {
    9. Thread.sleep(1000);
    10. } catch (InterruptedException e) {
    11. e.printStackTrace();
    12. }
    13. System.out.println(Thread.currentThread() + "waiting get resource2");
    14. synchronized (resource2) {
    15. System.out.println(Thread.currentThread() + "get resource2");
    16. }
    17. }
    18. }
    19. public void rightLeft() {
    20. synchronized (resource1) {
    21. System.out.println(Thread.currentThread() + "get resource1");
    22. try {
    23. Thread.sleep(1000);
    24. } catch (InterruptedException e) {
    25. e.printStackTrace();
    26. }
    27. System.out.println(Thread.currentThread() + "waiting get resource2");
    28. synchronized (resource2) {
    29. System.out.println(Thread.currentThread() + "get resource2");
    30. }
    31. }
    32. }
    33. }

  • 相关阅读:
    node.js 解析post请求 方法一
    Altium Designer学习笔记2
    Oracle11gr2 + plsql 配置
    计算机网络概述
    痞子衡嵌入式:i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad
    【Linux篇】第八篇——进程地址空间
    通俗易懂!一文看懂手机Root的操作与防护
    猿创征文|【React 三】组件实例的三大属性(state、props、refs)
    手写flexible.js的原理实现,我终于明白移动端多端适配
    向数据报表添加一个合计字段
  • 原文地址:https://blog.csdn.net/weixin_39283212/article/details/133201627