修复凌乱的代码中的死锁(Fixing deadlocks in messy code)

编程入门 行业动态 更新时间:2024-10-28 17:25:26
修复凌乱的代码中的死锁(Fixing deadlocks in messy code)

我正在修改一些非常复杂的代码,我需要在此基础上添加自己的同步。

但是,现有代码有大约十几个(如果不是更多)不同的锁,我的​​代码需要调用它的一些方法。 我真的不知道获取锁的顺序,我也无法真正控制它。

所以,我的问题是,如果我用一个锁替换所有不同的锁,会发生什么?。除了牺牲粒度,还有其他问题我应该注意吗?

谢谢!

I'm modifying a bit of seriously complex code and I need to add my own synchronization on top of this.

However, the existing code has about a dozen, if not more, different locks, and my code needs to call some of its methods. I don't really know the order in which the locks are being obtained, nor can I really control it.

So, my question is, what would happen if I replaced all the different locks by a single lock?.Apart from sacrificing granularity, is there any other issue I should be aware of?

Thanks!

最满意答案

如果您更改了所有synchronized块(和方法) 以及所有其他阻塞结构,我认为您应该没问题 - 最坏的情况是,您的应用程序退化为执行串行连接。 但是,如果你只更改其中一些,你可能会陷入僵局。 考虑两个线程各自获取多个锁的情况:

Thread 1: synchronized A synchronized B Thread 2: synchronized B synchronized C

这里没有死锁的风险,但如果用新的普通锁替换A和C (但不是B ),那么你将拥有:

Thread 1: synchronized L synchronized B Thread 2: synchronized B synchronized L

......这是典型的死锁案例。

考虑另一个场景,其中锁本身不提供死锁,而是像CountDownLatch一样死锁一个阻塞类:

Thread 1: synchronized A latch L.countDown() Thread 2: synchronized B latch L.await()

在这种情况下,更改两个synchronized块以锁定公共锁定不会导致它们之间的死锁,但如果线程2首先获得锁定将导致死锁:它将等待锁存器的countDown,这将永远不会到来,因为线程1是在synchronized入口点被阻止。 此示例也适用于其他阻塞结构:信号量,阻塞队列等。

If you change all of the synchronized blocks (and methods), and all the other blocking structures, I think you should be fine -- worst case, your app degenerates to having serial execution. But if you only change some of them, you could get deadlock. Consider a scenario where two threads are each acquiring multiple locks:

Thread 1: synchronized A synchronized B Thread 2: synchronized B synchronized C

There's no risk of deadlock here, but if you replace A and C (but not B) with the new, common lock, then you'll have:

Thread 1: synchronized L synchronized B Thread 2: synchronized B synchronized L

... which is the classic deadlock case.

Consider another scenario, where the locks don't provide deadlock themselves, but instead deadlock a blocking class like a CountDownLatch:

Thread 1: synchronized A latch L.countDown() Thread 2: synchronized B latch L.await()

In this case, changing both synchronized blocks to lock on a common lock won't cause deadlock between them, but will cause deadlock if thread 2 gets the lock first: it'll await the latch's countDown, which will never come because thread 1 is blocked at its synchronized entry point. This example applies to other blocking structures, too: semaphores, blocking queues, etc.

更多推荐

本文发布于:2023-07-26 10:34:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1274382.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:死锁   凌乱   代码   Fixing   messy

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!