• 重新认识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. }

  • 相关阅读:
    麒麟KYLINIOS软件仓库搭建02-软件仓库添加新的软件包
    隆重推出 Incredibuild 10
    KubeGems 启用 Nacos 配置中心
    Linux操作系统-信号量
    MySQL-数据库事务详解
    神经网络的三种训练方法,神经网络训练全过程
    二维码登录的原理
    2023秋招—大数据开发面经—卓望数码
    整合vue elementui springboot mybatisplus前后端分离的 简单增加功能 删改查未实现
    ASEMI整流桥GBJ3510参数,GBJ3510特征,GBJ3510大小
  • 原文地址:https://blog.csdn.net/weixin_39283212/article/details/133201627