gpt4 book ai didi

java - 如何解决这个僵局?

转载 作者:行者123 更新时间:2023-11-30 08:39:32 25 4
gpt4 key购买 nike

我在代码中添加了注释来解释死锁发生的位置。基本上,有两个线程。每个线程获取一个 Manager 对象的锁,然后获取静态资源的锁,静态资源是应用程序中所有 Manager 对象的映射。两个线程都调用 get() 在 map 上。Manager 类重写了 equals() 方法。 equals() 进一步调用了一些Manager 类的同步方法。因此, map 上的 get() 需要对 map 中的每个对象进行对象级锁定,直到键匹配为止,因为 equals 被覆盖了。我只能更改子类(Sub1Sub2)中的代码并避免死锁,因为我无权访问其他类。

编辑:我无权访问 syncMap。 “同步” block 中的代码在我调用其 API 的第三方代码中执行。

我可以通过在 Manager 上的 finally 中获取锁来避免这种情况,而不是在 try block 之前获取锁吗?!

    public class Parent{
protected Manager manager;
}

public class Global{
private static final Map syncMap = Collections.synchronizedMap(new HashMap());
//syncMap contains all the objects of Manager in the application
}

class Manager{


public boolean equals(Object o){

Manager obj = (Manager)o;
return obj.getURL().equals(getURL());
}

public final synchronized String getURL(){
return msettings.getDBURL(); //msettings is a global variable
}


}


//Thread-1 is executing someMethod() of this class

class Sub1 extends Parent{
Global global;
//consider manager and Global object are not null
public void someMethod()
{
synchronized(manager){// Thread-1 succesfully takes object level lock on a manager object, say Manager01
try{
global.syncMap.get(manager);
// Thread-1 Succesfully takes class level lock on syncMap
// get() calls equals() for each object in syncMap.
//equals() need object lock on each Manager Object in map as it further calls synchronized getURL()
// But on one manager Object(Manager02) Thread-2 has already acquired lock and is waiting for lock on syncMap which this thread-1 holds

}
finally{
manager.releaseConnection();
}

}
}
}

//Thread-2 is executing otherMethod() of this class
class Sub2 extends Parent{
public void otherMethod()
{
synchronized(manager){// this takes a lock on manager(Manager02)
try{
global.syncMap.get(manager);
// this is blocked as syncMap is aquired by thread-1


}
finally{
manager.releaseConnection();
}

}
}
}

最佳答案

在新的部分信息之后,除了将所有处理转换为串行方式外,我看不到其他解决方案。因此,您可以将所有与管理器相关的 API 调用放在某个包装类的一个同步方法中,并将此包装器用作第三方 API 的单个入口点。

class BrutalWrapper {
public synchronized void doIt(Manager manager)
{
try{
global.syncMap.get(manager);

}
finally{
manager.releaseConnection();
}
}
}

class Sub1 extends Parent{
BrutalWrapper brutal;
public void someMethod()
{
brutal.doIt(manager);
}
}

class Sub2 extends Parent{
BrutalWrapper brutal;
public void someMethod()
{
brutal.doIt(manager);
}
}

关于java - 如何解决这个僵局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36082981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com