
全部展开

JAVA中的几个常见死锁和对策: 没有简单的方法可以解决死锁. 这是因为线程由于各种原因而具有死锁,并且它们通常具有很高的负载. 大多数软件测试不会产生足够的负载,因此不可能暴露所有线程错误. 在这里,下面将讨论开发过程和解决方案中常见的四个典型死锁. (1)死锁在中,如果一个连接占用了另一个连接所需的锁,则它可以阻止另一个连接. 如果两个或多个连接彼此阻塞,则它们将无法继续执行,这种情况称为死锁. 死锁问题不容易解决. 通常,当更新数据行时,您需要锁定数据行,执行更新,然后在提交或回滚已关闭的事务时释放该锁. 由于平台不同,配置的隔离级别和查询提示不同,获得的锁可能是细粒度的也可以是粗粒度的. 它可以阻止(或不阻止)同一数据行,表或上的其他查询. 根据模式,读和写操作将需要遍历或更新多个索引,验证约束,执行触发器等. 每个请求都引入一个锁. 此外,其他应用程序可能正在访问同一架构中的某些对象,并获取不同应用程序拥有的锁. 综合所有这些因素,几乎不可能消除死锁. 幸运的是,死锁通常是可恢复的: 当发现死锁时,它将强制破坏连接(通常是最少使用的连接)并回滚其事务.

这将释放与已结束的事务关联的所有锁,至少允许其他连接之一获取它们正在阻止的锁. 因为具有这种典型的死锁处理行为,所以当发生死锁问题时,通常只能重试整个事务. 销毁连接后,将引发应用程序可以捕获的异常并将其标识为死锁. 如果允许死锁异常传播到启动事务的代码层之外,则代码层可以启动新事务并重做所有先前的工作. 出现问题时,请重试,因为可以自由获取锁,所以几乎不可能确保两个或多个线程不会导致死锁. 此方法至少可以确保当某些出现死锁时,应用程序可以正常运行. (2)资源池耗尽死锁客户端数量的增加导致资源池耗尽死锁是由负载引起的,即资源池太小,每个线程所需的资源超过了池中的可用资源. 假定连接池最多有10个连接,并且有10个并发呼叫到外界. 这些线程中的每一个都需要连接以清空池. 现在,每个线程都执行嵌套调用. 这样,所有线程将无法继续,但不会放弃其第一个连接. 这样,10个线程将被死锁. 研究这种类型的死锁,您会发现线程存储中有大量线程在等待获取资源,并且有相等数量的空闲和非阻塞活动连接. 当应用程序死锁时,如果可以在运行时检测到连接池,则可以确认该连接池实际上为空.

解决此类死锁的方法包括: 增加连接池的大小或重构代码,以便单个线程不需要同时使用多个连接. 或者,您可以将内部呼叫设置为使用其他连接池. 即使外部呼叫的连接池为空,内部呼叫也可以使用其自己的连接池继续进行. (3)单线程,多冲突的连接死锁有时会执行对同一线程的死锁调用. 即使在非高负载系统中也通常会发生这种情况. 当第一个(外部)连接获得第二个(内部)连接所需的锁定时,第二个连接将永久性阻塞第一个连接,并等待第一个连接被提交或回滚. 发生了死锁情况. 因为没有注意到两个连接之间的关系,所以不会将这种情况检测为死锁. 即使没有并发,此代码也将导致死锁. 这种情况有许多特定的变体,其中可能涉及多个线程和两个以上的连接. (4)当锁和Java虚拟机锁共存时,就会发生Java虚拟机锁和锁之间的冲突. 在这种情况下,线程将持有锁多线程如何避免死锁,并尝试获取Java虚拟机锁. 同时,另一个线程持有Java虚拟机锁,并尝试获取锁. 此时,发现一个连接正在阻塞另一个连接,但是由于无法阻止连接继续,因此它将无法检测到死锁. Java虚拟机发现同步锁中有一个线程,另一个线程正在尝试进入,因此即使Java虚拟机可以检测到死锁并对其进行处理,也仍然不会检测到这种情况.

总而言之,e68a84e8a2ad7a686964616f31333363373664,JAVA应用程序中的死锁是一个大问题-它可能导致整个应用程序缓慢终止,并且难以分离和修复,尤其是当开发人员不熟悉如何分析死锁时环境时间. 五,死锁的经验法则作者总结了以下有关开发中死锁问题的经验. (1)对于大多数Java程序员而言,防止死锁的最简单方法是在竞争资源中引入序列号. 如果线程需要多个资源,则在申请大序列号之前,它必须首先获取序列号小的资源. H.您可以在Java代码中增加使用同步关键字,这样可以减少死锁,但是这样做也会影响性能. 如果负载太重,则内部可能会发生死锁. (2)了解锁的行为. 假定任何访问都可能陷入死锁的情况,但是可以正确地重试. 例如,学习如何从应用程序服务器获取完整的线程转储以及如何从获取连接(包括阻塞的连接)的列表多线程如何避免死锁,并了解每个连接与哪个Java线程相关联. 理解Java线程和连接之间的映射的最简单方法是将日志记录添加到连接池访问模式. (3)进行嵌套调用时,请了解哪些调用使用与其他调用相同的连接. 即使嵌套调用在同一全局事务中运行,它仍将使用不同的连接而不会导致嵌套死锁. (4)确保在并发高峰期有足够大的资源池. (5)占用Java虚拟机锁时,避免执行调用或执行与Java虚拟机无关的其他操作. 最重要的是,尽管多线程设计很困难,但是在开始编程之前详细设计系统可以帮助您避免发现死锁的问题. 死锁无法在语言级别解决,因此需要一种良好的设计来避免死锁.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-172919-1.html
祖宗留给我们的江海疆土绝不容侵犯
象是给美国出一出气
不配做人