1

XYの正の側にのみ存在できる円を実装するCircleImplクラスがあります(半径> = 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はそれ自体をロックし(this)、「other」をロックする前に(c2)c2はCPU時間を取得して自身をロックし(c2)、「other」をロックしようとし(c1)、ブロッキングモードに入ります。

リソースの順序付け(System.identityHashCode)を含まない、これに対する可能なSIMPLEソリューションは何ですか?

4

1 に答える 1

2

単純な(しかし実際には効率的ではない)解決策はunion、共有オブジェクト(たとえば、)の操作を同期することCircle.classです。欠点は、常にunion1つのスレッドに対してのみ実行できることです。何かのようなもの:

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())); 
    } 
} 
于 2013-02-03T18:37:12.537 に答える