0

こんなユースケースがあります。私のメソッドの 1 つは、List をパラメーターとして受け取ります。オブジェクトの少なくとも 1 つが他のスレッドによって既にロックされている場合にのみ、クリティカル セクションを保護する必要があります。java.util.concurrent パッケージを使用してどのように達成できますか? 次のような単純な HashTable ベースのソリューションを考えることができます

class ContainsCriticalSections {
    HashTable<SomeObject, Thread> map; //shared by multiple threads

    someCriticalMethod(List<SomeObject> objects) {
        acquireLocks(objects);
        //do critical task
        releaseLocks(objects);
    }

    synchronized acquireLock(List<SomeObject> objects) {
        bool canLock = false;
        while (!canLock) {
               for (SomeObject obj : objects) {
                   if (!map.contains(obj)) {
                       canLock = true;   
                   }
                   else if(map.get(obj).equals(Thread.currentThread())) {// ensuring re-entrace
                       canLock = true; 
                   }
                   else {
                       canLock = false;    
                   }
               }
               if (!canLock) {
                   wait();
               }
        }
        for (SomeObject obj : objects) {
                   map.put(obj, Thread.currentThread());
        }   

    } 

    synchronized releaseLock(List<SomeObject> objects) {
            for (SomeObject obj : objects) {
                   map.reomve(obj);
            }
            notify();
    }

  }

したがって、上記の場合、A、B、C と D、E、F を使用した 2 つの呼び出しがブロックされない場合。ただし、A、B、C と A、E、F はブロックします。

しかし、ここには確立されたパラダイムがあると強く感じています (java.util.Concurrent を使用)。

4

2 に答える 2

1

すべてのロックを取得する必要があります。そうしないと、クリティカルセクションに入ったときに誰もロックを保持していなくても、中にいる間に誰かがロックを取得する可能性があります。いくつかのロックの下でタスクを実行するために使用できるメソッドは次のとおりです。

public static void runUnderMultipleLocks (Runnable task, Object ... monitors)
{
    runUnderMultipleLocks (task, 0, monitors);
}

private static void runUnderMultipleLocks (Runnable task, int offset, Object ... monitors)
{
    if (offset == monitors.length) task.run ();
    else
    {
        synchronized (monitors [offset])
        {
            runUnderMultipleLocks (task, offset + 1, monitors);
        }
    }
}
于 2013-02-07T10:09:11.947 に答える
1

を探しているのではないかと思いますReadWriteLock例については、 ReentrantReadWriteLockを参照してください。

ロックは複数のReadWrite同時ロックを許可しますReadが、ロックを取得しようとすると、Writeすべてのロック (ReadまたはWrite) が解放されるまでブロックされます。

したがって、他のすべてのメソッドがロックをList要求している間に、 を受け取るメソッドがロックを要求する必要があります。WriteRead

于 2013-02-07T10:34:27.733 に答える