簡體   English   中英

簡單的LinkedList和隊列同步

[英]Simple LinkedList and Queue synchronization

對於大學作業,我需要實施醫院病人等待系統的一部分。系統使用等待名單上的患者集合,以及在特定時期(例如今年)注冊操作的一組患者。

我使用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;
    }
}

你這里只有一些代碼,但你的同步看起來不錯。

僅供參考,您的LinkedList.contains需要O(n) 我會做以下其中一項

  1. 使用具有常量查找但仍保持順序的LinkedHashSet 但是,根據您以后的使用情況,這可能不會令人滿意。

  2. 使用HashSet來擴充LinkedList 除了檢查.contains()時,請使用LinkedList

您可以考慮讀/寫鎖...但選擇這取決於您對用戶閱讀集合的頻率以及閱讀和寫作的期望。

A.用戶嘗試添加已存在的患者的次數(閱讀)

B.您經常閱讀上面未顯示的應用程序其他部分的列表(閱讀)

C.用戶成功添加患者的次數(讀取+寫入)

如果與C相比(A + B)很大,請考慮像java.util.concurrent.locks.ReentrantReadWriteLock這樣的讀/寫鎖。 調用readLock()開始讀取(只阻止編寫器,而不是其他讀取器),如果需要,釋放讀鎖定並調用writeLock()以升級到寫入(從而阻止所有其他讀取和寫入)。 獲得寫鎖定后,請務必重新檢查在讀鎖定階段檢查的斷言。

除此之外,您現有的同步看起來很好。

一個想法是ReadWriteLock。 因為在這部分代碼中:

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);
}

您阻止訪問整個列表,即使只是讀取列表不會導致任何線程問題,但是您需要鎖定以防以后指令可以寫入。 這是由ReadWriteLock解決的,通過授予無限制的讀訪問權限,除非有人真正想寫。 這可以像這樣實現:

lock.readLock().lock();
try {
  if(registeredPatients.contains(patient)) {
    return true;
  }
  if(waitingListPatients.contains(patient) ) {
    return false;
  }
} finally {
  lock.readLock().unlock();
}

//Not already registered so register or add to waiting list
lock.writeLock().lock();
try {
  // need to re-check here, as the list could have been changed in between
  if(registeredPatients.contains(patient)) {
    return true;
  }
  if(waitingListPatients.contains(patient) ) {
    return false;
  }
  return addPatient(patient);
} finally {
  lock.writeLock().unlock();
}

現在,如果許多線程只需要讀取,但很少寫入,這將提高應用程序的速度。 如果幾乎所有讀取的線程都寫入,這實際上會減慢速度,因為您不僅需要檢查兩次,還需要鎖定兩次。 另外,synchronized比鎖更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM