【校招VIP】Java如何检测死锁?

05月13日 收藏 0 评论 1 java开发

【校招VIP】Java如何检测死锁?

文章申明:转载来源:https://blog.csdn.net/jjclove/article/details/124379073

分析&回答

死锁的四个必要条件:

1)互斥条件:进程对所分配到的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
2)请求和保持条件:进程已经获得了至少一个资源,但又对其他资源发出请求,而该资源已被其他进程占有,此时该进程的请求被阻塞,但又对自己获得的资源保持不放。
3)不可剥夺条件:进程已获得的资源在未使用完毕之前,不可被其他进程强行剥夺,只能由自己释放。
4)环路等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, …, pn},其中 Pi 等待的资源被 P(i+1) 占有(i=0, 1, …, n-1),Pn 等待的资源被 P0占 有,如下图所示。

反思&扩展

如何避免死锁的日常思考

避免同一个线程同时获取多个锁。主副线程的加锁顺序一致。
避免同一个线程在锁内同时占用多个资源,尽量保证每一个锁只占用一个资源。
尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制.
对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况.
死锁检测

怎么预防死锁?

预防死锁的方式就是打破四个必要条件中的任意一个即可。

打破互斥条件:

在系统里取消互斥。若资源不被一个进程独占使用,那么死锁是肯定不会发生的。

但一般来说在所列的四个条件中,“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他几个必要条件,而不去涉及破坏“互斥”条件。。

打破请求和保持条件:

1)采用资源预先分配策略,即进程运行前申请全部资源,满足则运行,不然就等待。
2)每个进程提出新的资源申请前,必须先释放它先前所占有的资源。

打破不可剥夺条件:
当进程占有某些资源后又进一步申请其他资源而无法满足,则该进程必须释放它原来占有的资源。

打破环路等待条件:
实现资源有序分配策略,将系统的所有资源统一编号,所有进程只能采用按序号递增的形式申请资源

描述死锁,存活锁和饥饿的条件。描述这些情况的可能原因:

1、死锁 ( DeadLock ) 是一组无法进行的线程中的条件,因为组中的每个线程都必须获取已由组中的另一个线程获取的某些资源。最简单的情况是两个线程需要锁定两个资源才能进行,第一个资源已被一个线程锁定,第二个资源已被另一个线程锁定。
因为这些线程永远不会获得对两个资源的锁定,因此永远不会进展。

2、存活锁 ( LiveLock ) 是多线程对自己生成的条件或事件做出反应的一种情况。事件发生在一个线程中,必须由另一个线程处理。在此处理期间,发生的新事件必须在第一个线程中处理,依此类推。这样的线程是活着的并且没有被阻挡,但是仍然没有取得任何进展,因为它们用无用的工作压倒了对方

3、饥饿锁 ( Starvation ) 是线程无法获取资源的情况,因为其他线程(或多个线程)占用它太长时间或具有更高的优先级。线程无法取得进展,因此无法完成有用的工作。

C 1条回复 评论
琼华

起来更新了,老铁

发表于 2022-05-27 23:00:00
0 0