千家信息网

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

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要讲解了"java线程之死锁产生的原因是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"java线程之死锁产生的原因是什么"吧!一、什么是
千家信息网最后更新 2026年11月01日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安全错误 数据库的锁怎样保障安全 南京欣网互联网络科技有限公司 互联网科技公司简介 山东特亿宝互联网科技有限公司 云之行互联网科技 疫情对互联网科技公司影响 互联网科技小贷 万易互联网科技有限公司 互联网科技项目计划书材料类 互联网为啥属于高科技 青海科技产业互联网发展 中国科技创新与世界互联网大会 畅思互联网科技 互联网行业科技股 烟台灵鸽互联网科技有限公司 启辰互联网科技 互联网科技资金流入 米泉互联网科技专业怎么样 盐城市攀科互联网科技有限公司 陕西彩京云互联网科技有限公司 数字科技和互联网金融哪个好 山东特亿宝互联网科技有限公司 互联网和科技创新 互联网科技资迅 互联网科技开发公司 美国互联网黑科技 互联网企业和科技型企业 翼展科技 首家互联网医院 威龙国际互联网科技公司 21世纪互联网科技成就 恒生科技互联网指数十大成分股
0