2

アプリケーションの最初の起動時に、または単純にクリアMapできるオブジェクトがあります。nullマップが初期化されるまで、このマップにアクセスするすべてのスレッドをブロックする必要があります。その後、すべてのスレッドにこのマップにアクセスするように通知する必要があります。

このマップは構成データを保持し、単一のスレッドが新しい構成データをロードするためにリフレッシュすることを決定しない限り、読み取り専用になります (したがってSynchronized、私も必要とは思わないため、パフォーマンスのために必要ありません)。Conditiona にオブジェクトを使用しようとしましたReentrantLockが、 orIllegalMonitorStateを試みるたびに例外がスローされました。signalAll()await()

ここに私がする必要があることの疑似コードがあります:

void monitorThread{
    while(someCondition){
        map = updatedMap();
        condition.signalAll();
    }
}

String readValueFromMap(String key){
    if(map == null){
        condition.await();
    }
    return map.get(key);
}
4

3 に答える 3

4

CountDownLatchは、あなたが必要とすることすべてです。

CountDownLatch latch = new CountDownLatch(1); 

ハッシュマップの初期化中に実行latch.countdown()し、スレッドで使用するlatch.await()

void monitorThread{
    map = updatedMap();
    latch.countDown();
}

String readValueFromMap(String key){
    latch.await();
    return map.get(key);
}

await()CountDownLatchメソッドは、countdown が 0 より大きい場合にのみ待機するため、初回のみであることに注意してください。

于 2012-09-04T13:40:40.703 に答える
3

これを正しく行うには、メモリ バリアが必要ですvolatile。マップは最初は null である可能性があるため、別のロック オブジェクトが必要になります。以下が機能するはずです。

private final Object lockObject = new Object();
private volatile Map<...> map;

void monitorThread{
    while (condition){
        // do this outside of the synchronized in case it takes a while
        Map<...> updatedMap = updatedMap();
        synchronized (lockObject) {
           map = updatedMap;
           // notify everyone that may be waiting for the map to be initialized
           lockObject.notifyAll();
        }
    }
}

String readValueFromMap(String key) {
    // we grab a copy of the map to avoid race conditions in case the map is
    // updated in the future
    Map<...> mapRef = map;
    // we have a while loop here to handle spurious signals
    if (mapRef == null) {
        synchronized (lockObject) {
           while (map == null) {
               // wait for the map to initialized
               lockObject.wait();
           }
           mapRef = map;
        }
    }
    return mapRef.get(key);
}
于 2012-09-04T13:51:56.557 に答える