繁体   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