0

私は、読者が二重チェックのロックを使用して書き込みロックを取得する Java ReadWriteLock を作成しました。これは安全ではありませんか (遅延インスタンス化を使用した DCL の場合と同様)?

import java.util.concurrent.atomic.AtomicInteger;

public class DCLRWLock {
    private boolean readerAcquiringWriteLock = false;
    private boolean writerLock = false;
    private AtomicInteger numReaders = new AtomicInteger();

    public void readerAcquire() throws InterruptedException {
        while (!nzAndIncrement(numReaders)) {
            synchronized (this) {
                if (numReaders.get() != 0)
                    continue;
                if (readerAcquiringWriteLock) {
                    do {
                        wait();
                    } while (readerAcquiringWriteLock);
                } else {
                    readerAcquiringWriteLock = true;
                    writerAcquire();
                    readerAcquiringWriteLock = false;
                    assert numReaders.get() == 0;
                    numReaders.set(1);
                    notifyAll();
                    break;
                }
            }
        }
    }

    public void readerRelease() {
        if (numReaders.decrementAndGet() == 0)
            writerRelease();
    }

    public synchronized void writerAcquire() throws InterruptedException {
        while (writerLock)
            wait();
        writerLock = true;
    }

    public synchronized void writerRelease() {
        writerLock = false;
        notifyAll();
    }

    // Atomically:
    // If x is nonzero, increments x and returns true
    // Otherwise returns false
    private static boolean nzAndIncrement(AtomicInteger x) {
        for (;;) {
            int val = x.get();
            if (val == 0)
                return false;
            else if (x.compareAndSet(val, val + 1))
                return true;
        }
    }
}

Java には既に ReentrantReadWriteLock があることを知っています。DCL のどの形式が安全かどうかを判断する方法についての一般的な質問に興味がありますか?

4

1 に答える 1

5

DCL の危険性は、共有変数から null 以外の参照を読み取ったという理由だけで、参照を書き込んだスレッドによるすべての書き込みが表示されると想定したときに発生します。言い換えれば、データレースを介して公開された参考文献を読み、うまくいくと仮定します。

あなたの場合、データ競合さえありませんが、アトミック変数の競合状態だけです。したがって、上記の非安全性はここでは当てはまりません。

于 2013-08-13T11:26:28.073 に答える