门户网站的营销特点物流网站给做软件
2026/3/23 3:36:32 网站建设 项目流程
门户网站的营销特点,物流网站给做软件,做毕业设计资料网站好,怎么做页游文章目录Java死锁剖析与预防之道#xff1f;一、什么是死锁#xff1f;二、死锁的“四大金刚”条件1. **互斥#xff08;Mutual Exclusion#xff09;**2. **占有且等待#xff08;Hold and Wait#xff09;**3. **不可抢占#xff08;No Preemption#xff09;**4. **…文章目录Java死锁剖析与预防之道一、什么是死锁二、死锁的“四大金刚”条件1. **互斥Mutual Exclusion**2. **占有且等待Hold and Wait**3. **不可抢占No Preemption**4. **循环等待Circular Wait**三、常见死锁场景分析场景一银行转账问题场景二文件共享问题四、如何预防死锁1. **打破“循环等待”条件**2. **使用超时机制**3. **避免嵌套锁**4. **使用数据库事务**五、总结如果还有其他疑问欢迎留言讨论 领取 | 1000 套高质量面试题大合集无套路闫工带你飞一把Java死锁剖析与预防之道作为一个在Java世界摸爬滚打多年的“闫工”今天咱们来聊一个既有趣又有点棘手的话题——Java中的死锁Deadlock。说到死锁相信很多同学都经历过那种抓狂的时刻程序突然卡住不动了CPU却在疯狂运转日志里没有报错信息排查起来还得像福尔摩斯一样抽丝剥茧。不过别担心今天闫工就带着大家一起来揭开死锁的“庐山真面目”手把手教你们如何识别、分析以及预防它。废话不多说咱们直接上车一、什么是死锁在Java中死锁是指两个或多个线程互相等待对方释放资源从而导致所有相关线程都无法继续执行的状态。简单来说就是“大家都等别人先动结果谁都不动了”。举个生活中的例子假设你和小明两个人一起开门闩你负责开左边的门他负责开右边的门。如果你们两个同时卡住对方的动作比如你非要等小明把右边的门开了才能开左边的门那么大家就都会一直等下去直到天荒地老。这个例子完美诠释了死锁的核心问题资源竞争与顺序依赖。二、死锁的“四大金刚”条件要彻底搞懂死锁咱们得先了解它的四个必要条件。这四个条件就像是死锁的“DNA”只要满足它们中的任意一个就能避免死锁的发生。1.互斥Mutual Exclusion某些资源只能被一个线程独占访问不允许共享。比如Java中的ReentrantLock同一个时间点只有一个线程能持有这个锁。publicclassDeadlockExample{privatefinalObjectlockAnewObject();privatefinalObjectlockBnewThread();publicvoidmethodA(){synchronized(lockA){// 锁A被线程1占用System.out.println(线程1获得了锁A);try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lockB){// 线程1尝试获取锁B但此时锁B可能被其他线程占用System.out.println(线程1获得了锁B);}}}publicvoidmethodB(){synchronized(lockB){// 锁B被线程2占用System.out.println(线程2获得了锁B);try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lockA){// 线程2尝试获取锁A但此时锁A可能被其他线程占用System.out.println(线程2获得了锁A);}}}publicstaticvoidmain(String[]args){DeadlockExampleexamplenewDeadlockExample();Threadthread1newThread(()-example.methodA());Threadthread2newThread(()-example.methodB());thread1.start();thread2.start();}}在这个示例中线程1和线程2分别尝试获取锁A和锁B。如果它们的执行顺序不一致就有可能导致死锁。2.占有且等待Hold and Wait一个线程已经占用了至少一个资源同时还在等待其他资源。比如上面的例子中线程1已经占用了锁A但还在等待锁B被释放。3.不可抢占No Preemption资源不能强行从线程中剥夺只能由线程自己释放。这点在Java的ReentrantLock机制中体现得尤为明显——只有当前持有锁的线程才能通过调用unlock()方法来释放它。4.循环等待Circular Wait存在一个线程链每个线程都在等待下一个线程释放资源。比如线程1在等线程2释放资源而线程2又在等线程1释放资源。三、常见死锁场景分析场景一银行转账问题假设我们有一个简单的银行账户转账系统两个账户A和B需要从A转到B。如果不加适当的同步机制就可能引发死锁。publicclassBankTransfer{privatefinalObjectlockAnewObject();privatefinalObjectlockBnewThread();publicvoidtransferFromAToB(){synchronized(lockA){// 线程1先锁定ASystem.out.println(线程1获得了锁A);try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lockB){// 再尝试锁定B但此时可能被其他线程占用System.out.println(线程1完成了转账);}}}publicvoidtransferFromBToA(){synchronized(lockB){// 线程2先锁定BSystem.out.println(线程2获得了锁B);try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lockA){// 再尝试锁定A但此时可能被其他线程占用System.out.println(线程2完成了转账);}}}publicstaticvoidmain(String[]args){BankTransfertransfernewBankTransfer();Threadthread1newThread(()-transfer.transferFromAToB());Threadthread2newThread(()-transfer.transferFromBToA());thread1.start();thread2.start();}}场景二文件共享问题多个线程试图读取和写入同一个文件但如果没有合理的锁顺序管理就可能陷入死锁。四、如何预防死锁既然了解了死锁的成因咱们就得想想办法怎么预防它。闫工这里有几招“杀手锏”让你从此远离死锁的困扰。1.打破“循环等待”条件确保所有线程在获取资源时遵循相同的顺序。比如总是先获取锁A再获取锁B而不是反过来。这样可以避免出现相互等待的情况。publicclassDeadlockPrevention{privatefinalObjectlockAnewObject();privatefinalObjectlockBnewThread();publicvoidmethod(){synchronized(lockA){// 先锁定ASystem.out.println(获得了锁A);try{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lockB){// 再锁定B确保顺序一致System.out.println(完成了操作);}}}publicstaticvoidmain(String[]args){DeadlockPreventionpreventionnewDeadlockPrevention();Threadthread1newThread(()-prevention.method());thread1.start();}}2.使用超时机制在尝试获取锁时设置超时时间避免无限期等待。publicclassTimeoutLock{privatefinalReentrantLocklockAnewReentrantLock();privatefinalReentrantLocklockBnewReentrantLock();publicvoidmethod(){booleanacquiredAfalse;booleanacquiredBfalse;try{acquiredAlockA.tryLock(100,TimeUnit.MILLISECONDS);if(acquiredA){System.out.println(获得了锁A);acquiredBlockB.tryLock(100,TimeUnit.MILLISECONDS);if(acquiredB){System.out.println(完成了操作);}else{System.out.println(未能获得锁B放弃操作);}}else{System.out.println(未能获得锁A放弃操作);}}catch(InterruptedExceptione){e.printStackTrace();}finally{if(acquiredA)lockA.unlock();if(acquiredB)lockB.unlock();}}publicstaticvoidmain(String[]args){TimeoutLocktimeoutLocknewTimeoutLock();Threadthread1newThread(()-timeoutLock.method());thread1.start();}}3.避免嵌套锁不要在一个线程中同时持有多个锁尽量减少锁的嵌套层级。4.使用数据库事务在数据库操作中合理设计事务隔离级别和锁定机制可以有效避免死锁的发生。五、总结通过本文的分析我们了解了什么是死锁以及它在Java多线程编程中的常见场景。同时也学习了几种有效的预防措施比如确保资源获取顺序一致、使用超时机制等。希望这些内容能帮助你在实际开发中避免死锁问题写出更健壮的代码。如果还有其他疑问欢迎留言讨论 领取 | 1000 套高质量面试题大合集无套路闫工带你飞一把成体系的面试题无论你是大佬还是小白都需要一套JAVA体系的面试题我已经上岸了你也想上岸吗闫工精心准备了程序准备面试想系统提升技术实力闫工精心整理了1000 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 详细解析并附赠高频考点总结、简历模板、面经合集等实用资料✅ 覆盖大厂高频题型✅ 按知识点分类查漏补缺超方便✅ 持续更新助你拿下心仪 Offer免费领取 点击这里获取资料已帮助数千位开发者成功上岸下一个就是你✨

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询