线程死锁是什么

线程死锁是什么线程死锁:两个或两个以上的线程在执行过程中同时被阻塞,它们中的某个或者全部都在等待某个资源被释放,由于线程被无限期的阻塞,系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程被称为线程死锁如上图所示,线程A持有资源2,线程B持有资源1,它们都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态如果想要了解什么是线程阻塞的朋友,可以看我之前发的一篇线程的阻塞线程死锁示例代码如下:线程A通过synchronized(resource1)获得resource1的监视器锁,然后通

大家好,又见面了,我是你们的朋友全栈君。

线程死锁:

两个或两个以上的线程在执行过程中同时被阻塞,它们中的某个或者全部都在等待某个资源被释放,由于线程被无限期的阻塞,系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程被称为线程死锁

线程死锁是什么
线程死锁的演示

 如上图所示,线程A持有资源2,线程B持有资源1,它们都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态

 如果想要了解什么是线程阻塞的朋友,可以看我之前发的一篇线程的阻塞

线程死锁示例代码如下:

public class Demo {

    private static Object resource1 = new Object();    //资源 1
    private static Object resource2 = new Object();    //资源 2

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (resource1) {
                System.out.println(Thread.currentThread() + "get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "线程 1").start();
        new Thread(() -> {
            synchronized (resource2) {
                System.out.println(Thread.currentThread() + "get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "线程 2").start();
    }
}

输出结果:
Thread[线程 1,5,main]get resource1
Thread[线程 2,5,main]get resource2
Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1

线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到CPU执行权,然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁

 不了解synchronized的友友们,可以翻我之前的一篇关于synchronized

形成死锁的四个必要条件:

  1. 互斥条件:线程(进程)对于所分配到的资源具有排它性,即一个资源只能被一个线程(进程)占用,直到被该线程(进程)释放
  2. 请求与保持条件:一个线程(进程)因请求资源而被阻塞时,对以获得的资源保持不放
  3. 不剥夺条件:线程(进程)已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源
  4. 循环等待条件:当发生死锁时,所等待的线程(进程)必定会形成一个环路(类似于死循环),造成永久阻塞

实际应用中,为了避免线程死锁,必须打破其中一个条件:

  • 互斥条件没有办法破坏,因为我们用锁本来就是想让它们互斥的(临界资源需要互斥访问)
  • 破坏请求与保持条件,一次性申请所有资源
  • 破坏不剥夺条件,占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放该线程占有的资源
  • 破坏循环等待条件,按某一顺序申请资源来预防死锁,释放资源则按此顺序的反序来释放

大家有不理解可以翻我博客哦!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158542.html原文链接:https://javaforall.net

(0)
上一篇 2022年7月13日 上午11:16
下一篇 2022年7月13日 上午11:16


相关推荐

  • 【SQL Server】网上购物商城数据库设计报告(专业课设作品附上sql文件文档)

    【SQL Server】网上购物商城数据库设计报告(专业课设作品附上sql文件文档)目录一 需求分析 1 1 背景 1 2 数据需求 1 3 事物需求 1 4 数据流程图二 概念结构设计 2 1E R 图三 关系模式 3 2 数据逻辑结构四 物理结构设计 4 1 建立一个数据库 4 2 建立八张表 4 3 建立表的连接五 系统功能的实现 5 1 数据库建立 5 2 创建立数据表 5 3 建立表连接 5 4 数据初始 5 4 1 管理員初姶化 5 4 2 添加商品組信息 5 4 3 在各商品組加入商品 5 4 4 添加注册会員信息 5 4 6 添加枚限信息 5 4 7 添加管理员权限信息 5 5 查询 5 5 1 查询本站有哪些种类的商

    2025年10月25日
    6
  • flume使用教程_三阶魔方初级入门教程详细图解

    flume使用教程_三阶魔方初级入门教程详细图解文章目录1.Flume概述1.1Flume定义1.Flume概述1.1Flume定义  

    2025年8月1日
    2
  • VS Code 必备插件推荐「建议收藏」

    VS Code 必备插件推荐「建议收藏」插件说明备注AutoCloseTag自动添加HTML/XML关闭标签AutoRenameTag自动重命名配对的HTML/XML标签Beautify格式化代码BracketPairColorizer颜色识别匹配括号CodeRunner非常强大的一款插件…

    2022年5月6日
    76
  • 近距离接触品牌与终端

    近距离接触品牌与终端

    2021年8月12日
    53
  • ldap 协议

    ldap 协议ldap 目录服务日常生活中 或者开发过程中 需要管理的目录有很多 如 人员组织管理 电话簿 地址簿 字典表等 提供管理和查询目录信息的服务就是目录服务 有很多厂商实现了目录服务 但是对外提供的接口不统一 所以客户接入一个厂商之后想要切换厂商 成本很高 所以出现了 ldap 协议 ldap 协议规定所有的厂商对外提供接口的时候必须遵守统一的格式 客户端访问也遵循统一的格式

    2026年3月20日
    2
  • gcc命令的常用选项_curl常用命令及参数

    gcc命令的常用选项_curl常用命令及参数gcc是GUNC和C++编译器,我们通常使用GCC时,编译器会依次做如下工作:preprocess(预处理),compilation(编译),assembly(汇编),link(链接)。gcc提供了一些选项参数能够让编译器停在某个过程(如编译过程)。

    2022年10月13日
    6

发表回复

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

关注全栈程序员社区公众号