0

大学の課題では、病院の患者待機システムの一部を実装する必要があります。システムは、待機リストにある患者のコレクションと、今年などの指定された期間中の手術に登録された患者のセットを使用します。

HashSet と LinkedList を使用して、以下のように必要なメソッドを実装しました。メソッドはほぼ完全に同期されているので、同期の少ないより効率的な実装があるかどうか、またはロックを使用したより粒度の細かい読み書き同期があるかどうか疑問に思っていますか?

public Class OperationPeriod {
...
private Set<Patient> registeredPatients=new HashSet<Patient>();
private Collection<Patient> waitingListPatients=new LinkedList<Patient>();
    private int capacity;
...

    public boolean bookOperation(Patient patient){
    if (!Operation.checkHasMetRequirements(patient)) {
        return false;
    }

    //patient could already be registered
    synchronized(this) {
        if(registeredPatients.contains(patient)) {
            return true;
        }
        if(waitingListPatients.contains(patient) ) {
            return false;
        }
        //Not already registered so register or add to waiting list
        return addPatient(patient);
    }
}

private boolean addPatient(Patient patient) {
    if(registeredPatients.size() < capacity) {
        registeredPatients.add(patient);
        return true;
    }
    else {
        waitingListPatients.add(patient);
        return false;
    }
}
4

3 に答える 3

1

読み取り/書き込みロックを検討することもできますが、それを選択するかどうかは、ユーザーがコレクションの読み取りのみを行う頻度と、読み取りと書き込みを行う頻度の予測に依存します。

A. ユーザーがすでに存在する患者を追加しようとした回数 (読み取り)

B. 上記以外のアプリケーションの別の部分からリストを読み取る頻度 (読み取り)

C. ユーザーが患者を正常に追加した回数 (読み取り + 書き込み)

(A + B) が C に比べて大きい場合は、 のような読み取り/書き込みロックを検討してくださいjava.util.concurrent.locks.ReentrantReadWriteLock。readLock() を呼び出して読み取りを開始し (ライターのみをブロックし、他のリーダーはブロックしません)、必要に応じて読み取りロックを解放し、writeLock() を呼び出して書き込みにエスカレートします (それにより、他のすべての読み取りと書き込みをブロックします)。書き込みロックを取得したら、読み取りロック段階で確認したアサーションを必ず再確認してください。

それはさておき、既存の同期は問題ないようです。

于 2013-11-13T02:37:20.747 に答える
1

ここにはコードの一部しかありませんが、同期は問題ないようです。

参考までに、あなたのLinkedList.containsテイクO(n)。私は次のいずれかを行います

  1. LinkedHashSet一定のルックアップを持つが順序を維持する a を使用します。ただし、後でこれを使用することによっては、これで満足できない場合があります。

  2. を使用してHashSetを拡張しますLinkedListLinkedListをチェックするときは、except を使用し.contains()ます。

于 2013-11-13T02:31:33.173 に答える