2013-02-03 104 views
1

我有一个CircleImpl类,它实现一个圆圈,可以在XY的正侧仅存在(半径> = 0,X> =半径且y> =半径。)防止死锁

我在CircleImpl功能:

//this function changes the current circle (this) to make it contain the circle other. 
public synchronized void union(Circle other) throws Exception { 
if (!checkInv(other.getX(),other.getY(),other.getRadius())) 
    throw new Exception("Illegal circle: " + other); 
    synchronized (other) { 
    setRadius(calculateUnionRadius(_x,_y,_radius,other.getX(),other.getY(),other.getRadius())); 
    } 
} 

现在的问题是,这里死锁可能存在:

Circle c1,c2; 
… 
T1: c1.union(c2); 
T2: c2.union(c1); 

C1锁本身(这一点),并锁定前 “其他”(C2)C2获得CPU时间并锁定自己(C2)并尝试锁定“其他”(c1)并进入阻止模式。

什么可能SIMPLE解决方案,这不包括资源排序(System.identityHashCode)?

回答

2

简单(但并非真正有效)的解决方案是在共享对象上同步union操作,例如,在Circle.class。不利的一面是,它允许在任何给定时间仅对1个线程执行union。例如:

public void union(Circle other) throws Exception { 
    synchronized (Circle.class) { 
     if (!checkInv(other.getX(),other.getY(),other.getRadius())) { 
      throw new Exception("Illegal circle: " + other); 
     } 
     setRadius(calculateUnionRadius(_x,_y,_radius,other.getX(),other.getY(),other.getRadius())); 
    } 
} 
+0

+1如果'calculateUnionRadius'需要时间,在对各个变量进行本地复制之后,可以在synchronized块之外调用它。这可以减少争用。 – assylias

相关问题