当前位置: 首页 > 面试题库 >

如何避免嵌套同步和由此产生的死锁

冯德宇
2023-03-14
问题内容

我需要在功能中锁定两个对象,当前代码看起来像这样;

Object obj1  = ...//get from somewhere
Object obj2 = ...//get from somewhere

synchronized(obj1){
  ...//blah
  synchronized(obj2){
     ...//blah
  }
}

如您所见,如果另一个线程使用obj1和两个相反的代码运行这段代码,则这是死锁的简单明了的配方。
有没有一种方法可以使用concurrency-utils锁来避免这种情况?

我当时正在考虑维护一个对象及其锁的地图,并验证它们是否可供使用,但是似乎无法提出一种可以预测锁顺序的干净方法。


问题答案:

尽管您保留了锁定顺序,但是如果将obj1与obj2切换,则会遇到死锁。

您必须寻找另一种解决方案来避免这种情况:锁定顺序+可选的打破平局锁定

int fromHash = System.identityHashCode(obj1);
int toHash = System.identityHashCode(obj2);

if (fromHash < toHash) {
    synchronized (obj1) {
        synchronized (obj2) {
               ........
        }
    }
} else if (fromHash > toHash) {
    synchronized (obj2) {
        synchronized (obj1) {
            ........
        }
    }
} else {
    synchronized (TIE_LOCK) {
        synchronized (fromAcct) {
            synchronized (toAcct) {
               ...
            }
        }
    }


 类似资料:
  • 问题内容: 避免嵌套查询有多重要。 我一直学会避免像瘟疫一样躲避它们。但是对我来说,它们是最自然的事情。在设计查询时,我首先写的是嵌套查询。然后,我将其转换为联接,有时需要花费很多时间才能正确。而且很少会带来很大的性能提升(有时确实会提高) 他们真的那么糟糕吗?有没有一种方法可以使用没有临时表和文件排序的嵌套查询 问题答案: 这确实取决于我遇到的情况,我可以通过使用子查询来改进一些查询。 我知道的

  • 问题内容: 我正在通过oracle文档进行死锁..我找到了这段代码 我不明白,在什么情况下会发生死锁? 我运行此代码,它工作正常。因此必须有一些特殊事件,何时会发生死锁? 假设首先在对象上调用bow ,那么当在bower对象上调用bow时,它会在对象上保持锁定吗?因为如果它保留其锁定,则另一个对象上的函数只有保持其锁定状态才能获得锁定,并且永远不会出现死锁情况。 问题答案: 如果在打印第一行之后并

  • 问题内容: 我想制作一个页面来显示数据库中的某些数据,因此我创建了一些函数来从数据库中获取该数据。我只是Node.js中的新手,据我了解,如果我想在一个页面中使用它们(HTTP响应),则必须将它们全部嵌套: 如果有很多类似的功能,那么 嵌套就会成为问题 。 有办法避免这种情况吗?我想这与如何组合多个异步功能有关,这似乎是基本的东西。 问题答案: 有趣的观察。请注意,在JavaScript中,通常可

  • 主要内容:示例资源分配图是系统状态的图形表示。 顾名思义,资源分配图是关于持有一些资源或等待某些资源的所有进程的完整信息。 它还包含有关所有资源的所有实例的信息,无论这些资源是否可用或正在被进程使用。 在资源分配图中,进程由圆形表示,而资源由矩形表示。 我们来详细看看顶点和边的类型。 顶点主要有两种类型,资源和过程。 它们中的每一个将以不同的形状表示。 Circle代表进程,而矩形代表资源。 一个资源可以有多个

  • 在避免死锁的情况下,如果系统的结果状态不会导致系统中的死锁,那么将会授予对任何资源的请求。系统的状态将持续检查安全和不安全的状态。 为了避免死锁,进程必须告诉OS,进程可以请求完成其执行的最大资源数量。 最简单和最有用的方法指出,流程应声明它可能需要的每种类型的最大资源数量。 死锁避免算法检查资源分配,以便永远不会有循环等待条件。 安全和不安全的状态 系统的资源分配状态可以由可用资源和已分配资源的

  • 在Java,有没有一种方法可以避免在调用的每个级别上嵌套null检查,以确保沿途没有阻止下一次调用的null。有没有一个优雅的方法来做这件事? 例如: Objone.ObjTwo.ObjTree.ObjFour.ObjF