千家信息网

java线程之死锁产生的原因是什么

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,这篇文章主要讲解了"java线程之死锁产生的原因是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java线程之死锁产生的原因是什么"吧!一、什么是
千家信息网最后更新 2025年11月07日java线程之死锁产生的原因是什么

这篇文章主要讲解了"java线程之死锁产生的原因是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java线程之死锁产生的原因是什么"吧!

一、什么是死锁

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

二、死锁产生的原因

1、互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2、请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3、不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4、环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

三、死锁演示

1、synchronized

import lombok.Data;@Datapublic class Studnet {    private String name;}
 public static void main(String[] args) {        Studnet stu1=new Studnet();        stu1.setName("stu1");        Studnet stu2 = new Studnet();        stu2.setName("stu2");        new Thread(()->{            //加锁stu1            synchronized (stu1){                System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+stu1.getName());                try {                    //由于线程运行是native方法,我们增加线程睡眠,增加死锁概率                    TimeUnit.SECONDS.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }                //加锁stu2                synchronized (stu2){                    System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+stu2.getName());                }            }        },"t1").start();        new Thread(()->{            //加锁stu2            synchronized (stu2){                System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+stu2.getName());                try {                    //由于线程运行是native方法,我们增加线程睡眠,增加死锁概率                    TimeUnit.SECONDS.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }                //加锁stu1                synchronized (stu1){                    System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+stu1.getName());                }            }        },"t2").start();    }

2、lock

 public static void main(String[] args) {        Lock lock1=new ReentrantLock();        Lock lock2=new ReentrantLock();        new Thread(()->{            //加锁lock1            lock1.lock();            try {                System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+"lock1");                try {                    //由于线程运行是native方法,我们增加线程睡眠,增加死锁概率                    TimeUnit.SECONDS.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }                //加锁lock2                lock2.lock();                try {                    System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+"lock2");                }finally {                    //释放lock2                    lock2.unlock();                }            }finally {                //释放lock1                lock1.unlock();            }        },"t1").start();        new Thread(()->{            lock2.lock();            try {                System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+"lock2");                try {                    //由于线程运行是native方法,我们增加线程睡眠,增加死锁概率                    TimeUnit.SECONDS.sleep(1);                } catch (InterruptedException e) {                    e.printStackTrace();                }                lock1.lock();                try {                    System.out.println("线程:"+Thread.currentThread().getName()+",持有:"+"lock1");                }finally {                    lock1.unlock();                }            }finally {                lock2.unlock();            }        },"t2").start();    }

四、如何查看死锁

1、使用jps命令找到运行程序的pid

jps

2、jstack查看栈信息

jstack pid

发现了一个死锁

重点摘要,t1、t2线程,交叉持有锁,等待对方资源。

"t2":- waiting to lock <0x000000076b6f8428> - locked <0x000000076b6f8468>
#t2 等待锁0x000000076b6f8428,持有0x000000076b6f8468
"t1":- waiting to lock <0x000000076b6f8468> - locked <0x000000076b6f8428>
#t1 等待锁0x000000076b6f8468,持有0x000000076b6f8428

感谢各位的阅读,以上就是"java线程之死锁产生的原因是什么"的内容了,经过本文的学习后,相信大家对java线程之死锁产生的原因是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

线程 死锁 资源 进程 原因 运行 方法 概率 睡眠 条件 正在 学习 两个 内容 已获 已获得 系统 阻塞 作用 命令 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 虹口区网络技术服务咨询优势 中科院网络安全视频教程第九讲 地下城数据库 网络安全模式鼠标键盘无法使用 文献检索化学反应数据库 网络安全法为教育护航 青岛公安局网络安全岗工资 博雅数据库二本投挡线四川理科 更改服务器本地安全策略 sql数据库使用索引 计算机网络技术好写论文 柳州移动首选dns服务器 辽宁统一软件开发过程检测中心 智能边缘计算服务器选择 台州网站建设磐石网络安全 统筹兼顾网络安全 低学历网络安全专业就业前景 人工智能企业数据库系统的目的 软件开发公司平顶山 防范校园网络安全 长春网络安全培训机构免费试学 软件开发难度简述 瑞登网络技术公司陈泽斌 上海东纪互联网科技有限公司 防双网混插网络安全套件专利 sa数据库连接密码 北京太度快乐网络技术有限 怎么做测绘数据库 乐山软件开发方案 广西城管通软件开发
0