《Java synchronized死锁剖析:可重入锁及哲学家就餐问题探究》

《Java synchronized死锁剖析:可重入锁及哲学家就餐问题探究》

文章内容

各位朋友,咱们来聊聊多线程里synchronized涉及的死锁相关内容。上一回咱们初步认识了锁,知道用synchronized修饰代码块能把非原子操作变成原子操作,那synchronized只能修饰代码块吗?当然不是啦,它还能修饰方法呢,实例方法和静态方法都可以哦。

目录

  1. synchronized修饰方法
  2. synchronized是可重入锁
  3. 死锁
    3.1. 死锁的引入
    3.2. 哲学家就餐问题

1. synchronized修饰方法

下面是一些用synchronized修饰方法和代码块的示例:

synchronized public void increase(){    // synchronized修饰实例方法
    count++;
}
public void increase1(){
    synchronized (this){   // 用this作为锁对象
        count++;
    }
}

synchronized public static void increase2(){
    count++;
}
public void increase3(){
    synchronized (Demo1.class){  // 通过反射拿到这个类对象
        count++;
    }
}

一个.java文件经过编译会生成.class字节码文件,运行时.class文件会被加载到JVM里,此时JVM加载到内存中的数据结构就是类对象。解释:当JVM加载一个.class文件时,会在内存中创建对应的类对象结构,这个类对象包含类的属性、名称、类型、权限、类方法、继承关系、实现的接口等信息。

2. synchronized是可重入锁

那可重入锁到底啥意思呢?就是一个线程针对同一个对象连续加锁两次不会出现死锁情况。咱们用代码来举个例子:

synchronized (locker){
    synchronized (locker){
        count++;
    }
}

按理说这段代码可能会卡住,但synchronized是可重入锁,允许同一个线程连续给一个对象加锁。对象头里有个计数器,线程给对象加锁一次,计数器就加1。解释对象头和计数器:线程给对象加锁时,会在对象头的Mark Word里保存线程信息,每个对象都有对象头(Object Header),里面包含锁状态等元数据。一个线程连续给对象加锁时,计数器也在对象头的Mark Word里,这能保证同一个线程多次获取同一个对象的锁。解锁时:一个对象被加锁三次,计数器值是3,解锁时不是直接全释放,而是每解一次锁计数器减1,直到减到0才是真正释放锁。

3. 死锁

3.1. 死锁的引入

刚才知道了synchronized是可重入锁,那啥时候会出现死锁呢?看下面这段代码:

public static void main(String[] args) {

    Object locker1 = new Object();
    Object locker2 = new Object();
    Thread t1 = new Thread(() ->{
        synchronized (locker1){
            try {
                Thread.sleep(1000);
                // 这里休眠很关键,不然线程可能一下子就拿到两个锁了
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 嵌套加锁
            synchronized (locker2){
                System.out.println("t1加锁成功");
            }
        }


    });

    Thread t2 = new Thread(() -> {
        synchronized(locker2){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 嵌套加锁
            synchronized(locker1){
                System.out.println("t2 加锁成功");
            }
        }

    });

    t1.start();
    t2.start();

}

运行这段代码,结果啥都没打印。通过jconsole查看线程状态,能看到两个线程都没成功获取第二把锁。这属于嵌套加锁情况,线程A拿到locker1锁后又想拿locker2锁,就可能出现死锁。要是并列加锁(线程先释放前面的锁再获取下一把锁)就不会死锁,嵌套变并列可以通过改变代码结构实现。

3.2. 哲学家就餐问题

看下面这张图表示的哲学家就餐问题:

《Java synchronized死锁剖析:可重入锁及哲学家就餐问题探究》

这就导致了死锁问题。死锁形成通常有四个必要条件:
1. 互斥使用:锁的基本特性,一个线程拥有锁A,其他线程想获取就得阻塞等待。
2. 不可抢占:和条件一类似,其他线程只能等拥有锁的线程释放,不能强行抢占。
3. 保持请求:线程想获取多把锁(嵌套,想获取锁B但不想释放自己的锁),其实合理获取多把锁没问题,但会形成环导致死锁。
4. 循环等待:条件三导致的,等待关系形成环。

解决哲学家就餐问题可以通过约定加锁顺序,给锁编号,先加小锁再加大锁。比如规定每个哲学家先拿数字小的筷子,像哲学家B先拿筷子,最后哲学家A面前只剩数字大的筷子5,拿不了,而哲学家E就能吃到面条,这样就解决了死锁问题。

《Java synchronized死锁剖析:可重入锁及哲学家就餐问题探究》

以上就是synchronized死锁问题的全部内容啦,死锁会让程序陷入死循环,只要知道死锁成因就能找到解决办法啦~欲知后续如何,且听下回分解~

能看到这里说明您对文章有一定认可,有问题欢迎大佬指出,欢迎评论区留言修正哦~

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/13580.html

(0)
LomuLomu
上一篇 2025 年 9 月 17 日
下一篇 2025 年 9 月 17 日

相关推荐

  • IDEA 2024永久激活破解教程,附激活码和工具,实测有效

    【最新教程】IDEA 2024.1.2 永久激活破解方法,附激活码和工具,实测有效 IntelliJ IDEA 是目前 Java 开发中最受欢迎的集成开发环境之一,其强大的功能和智能提示使其在开发者中拥有极高的声誉。本文将介绍如何通过脚本和激活码免费激活 IDEA 2024.1.2 版本,确保您能够永久使用这款软件。 一、下载安装 IntelliJ IDEA…

    未分类 2024 年 7 月 8 日
    1.6K00
  • 🚀 2025年最新IDEA激活码分享:永久破解IDEA全系列教程(附破解补丁下载)

    💻 教程适用性说明 本教程完美适用于Jetbrains全家桶所有产品,包括但不限于:- IntelliJ IDEA 🔧- PyCharm 🐍- DataGrip 🗃️- GoLand 🦾- 其他Jetbrains系列IDE 先给大家看看最新IDEA 2024.3版本破解成功的实锤截图!有效期直接拉到2099年,简直不要太爽!🎉 下面我就手把手教大家如何实现永…

    2025 年 6 月 9 日
    1.7K00
  • 2026年 IDEA 激活码大全,按版本整理可直接使用

    这篇教程兼容IDEA、PyCharm、DataGrip、Goland等Jetbrains系列所有产品! 话不多说,先展示最新版IDEA破解成功的截图,如下图所示,激活有效期至2099年,非常给力! 下面,我将通过图文详解的方式,手把手教你如何将IDEA激活至2099年。 当然,本激活方案同样兼容历史旧版本! 无论你使用何种操作系统或软件版本,相关资源都已为你…

    IDEA破解教程 2026 年 4 月 10 日
    32800
  • 🔥 2025年最新PyCharm永久破解教程:一键激活至2099年(附激活码)🔥

    无论你是Windows、Mac还是Linux用户,无论你使用的是最新版还是旧版PyCharm,本教程都能帮你100%成功激活至2099年!💪 下面通过详细图文步骤,手把手教你如何操作~ 📥 下载PyCharm安装包 (已安装可跳过) 1. 访问官网:https://www.jetbrains.com/pycharm/download/ 2. 下载对应系统的安…

    2025 年 5 月 13 日
    1.2K00
  • 启发式算法里RRT的详尽剖析及Python实践

    深度解析启发式算法中的RRT及Python实现 文章引言 此篇文章是博主在研习人工智能领域时,用于自身学习、研讨或品鉴而记录的学习笔记,依据博主对相关领域的理解予以撰写。文章归类于👉启发式算法专栏:【启发式算法】(8)—《RRT算法详细介绍(Python)》 一、RRT算法的核心思想 RRT的核心要义是借助在空间里随机抽取采样点,逐步构建起树形结构的搜索…

    2025 年 7 月 4 日
    50400

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信