Java 在这种方法中是否可能出现死锁?我怎样才能预防它?

Java 在这种方法中是否可能出现死锁?我怎样才能预防它?,java,deadlock,Java,Deadlock,死锁与两个线程? 谢谢你的回答 当然 假设我们有两个物体 public void function(object a, object b){ synchronized(a){ synchronized (b){ a.performAction(b); b.performAction(a); } } } 假设线程1调用: Object one = ...; Object two = ...; 线程2调用

死锁与两个线程? 谢谢你的回答

当然

假设我们有两个物体

public void function(object a, object b){
    synchronized(a){
        synchronized (b){
           a.performAction(b);
           b.performAction(a);
        }
    }
}
假设线程1调用:

Object one = ...;
Object two = ...;
线程2调用时:

function(one, two);
在线程1中,
a==1
b==2
,但在线程2中,
a==2
b==1


因此,当线程1在对象1上获得锁时,线程2可以在对象2上获得锁。然后,当每个线程尝试执行下一步时,它们将处于死锁状态。

为了避免jame回答中所述的问题,您需要创建一个锁来保存这两个对象,无论它们传递给函数的顺序如何:

function(two, one);
在函数中,您需要以某种方式存储锁:

public class TwoObjectsLock {
    private Object a;
    private Object b;

    public TwoObjectsLock(Object a, Object b){
        this.a = a;
        this.b = b;
    }

    @Override
    public void equals(Object obj){
        if (this == obj) return true;
        if (obj instanceof TwoObjectsLock){
            TwoObjectsLock that = (TwoObjectsLock) obj;
            return (this.a.equals(that.a) && this.b.equals(that.b)) ||
                   (this.a.equals(that.b) && this.b.equals(that.a));
        }
        return false;
    }

    @Override
    public int hashCode(){
        return a.hashCode() + b.hashCode();
    }
}
private final Map lockInstances=new HashMap();
公共无效功能(对象a、对象b){
TwoObjectsLock=新TwoObjectsLock(a,b);
已同步(锁定实例){
TwoObjectsLock otherLock=lockInstances.get(lock);
if(otherLock==null){
lockInstances.put(锁,锁);
}
否则{
lock=otherLock;
}
}
已同步(锁定){
a、 执行(b);
b、 执行(a);
}
}

不是最佳,但可以工作。

否,两个线程都将等待“a”。这可能是因为有第二种方法,您首先在“b”上同步,然后在“a”上同步是否在同步方法中使用对象a?例如,会出现死锁?在提供的情况下否,因为线程1将等待对象“a”的释放,直到方法结束。实际上,我认为如果两个线程使用对象thread1(a,b)和线程2(b,a)执行funktion同时出现死锁,因为两个线程都在等待第二次同步中的对象,或者我错了吗?线程1(a,b)和线程2(b,a)-在这种情况下,是的,您可以通过按asc/desc哈希代码顺序锁定来修复。不管怎么说,这不好。
private final Map<TwoObjectsLock, TwoObjectsLock> lockInstances = new HashMap<>();

public void function(Object a, Object b){
    TwoObjectsLock lock = new TwoObjectsLock(a,b);
    synchronized(lockInstances){
        TwoObjectsLock otherLock = lockInstances.get(lock);
        if (otherLock == null){
            lockInstances.put(lock, lock);
        }
        else {
            lock = otherLock;
        }
    }

    synchronized(lock){
       a.performAction(b);
       b.performAction(a);
    }
}