2013-02-03 141 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

相關問題