繁体   English   中英

如何使循环队列完全线程安全

[英]How to make a circular queue completely thread safe

目前,我刚刚将同步添加到大多数方法中,因为如果没有同步,这些方法将不是线程安全的。 还有什么我需要实现的,以确保它是线程安全的。

此外,还有更好的方法可以解决此问题。 目前只有一个线程可以同时使用循环队列,这似乎效率很低。

class CircularQueue<T> implements Iterable<T>{
  private T queue[];
  private int head, tail, size;
  @SuppressWarnings("unchecked")
  public CircularQueue(){
     queue = (T[])new Object[20];
     head = 0; tail = 0; size = 0;
  }
  @SuppressWarnings("unchecked")
  public CircularQueue(int n){ //assume n >=0
     queue = (T[])new Object[n];
     size = 0; head = 0; tail = 0;
  }
  public synchronized boolean join(T x){
    if(size < queue.length){
        queue[tail] = x;
        tail = (tail+1)%queue.length;
        size++;
        return true;
     }
     else return false; 
  }
  public synchronized T top(){
    if(size > 0)
        return queue[head];
    else
        return null;
  }
  public synchronized boolean leave(){
    if(size == 0) return false;
    else{
        head = (head+1)%queue.length;
        size--;
        return true;
    }
  }
  public synchronized boolean full(){return (size == queue.length);}
  public boolean empty(){return (size == 0);}

  public Iterator<T> iterator(){
      return new QIterator<T>(queue, head, size);
  }
  private static class QIterator<T> implements Iterator<T>{
      private T[] d; private int index; 
    private int size; private int returned = 0;
      QIterator(T[] dd, int head, int s){
          d = dd; index = head; size = s;
      }
    public synchronized boolean hasNext(){ return returned < size;}
    public synchronized T next(){
        if(returned == size) throw new NoSuchElementException();
        T item = (T)d[index];
        index = (index+1) % d.length;
        returned++;
        return item;
    }
    public void remove(){}
  }
}

您可以提供的任何建议或帮助将不胜感激!

除了缺少使您的empty()方法同步之外,迭代器还无法与主机队列充分隔离。 问题不在于其方法在迭代器实例上是同步的,尽管确实如此。 您的迭代器正在复制主机队列的数据,以便遍历队列的快照。 那是个好主意,在这种情况下,在迭代器本身上进行同步是正确的事情。

但是您没有完全实现它。 具体来说,对于构造函数执行d = dd;是不够的d = dd; 数组是对象,因此只需将迭代器的数组引用设置为引用主机队列使用的同一数组对象。 相反,您需要复制该数组。 有几种方法可以做到这一点,但是我更喜欢调用数组的clone()方法-简短而甜蜜。

即使这样,仍然存在线程安全问题,仅靠类的方法同步是无法防御的。 其中一些涉及对象在多个方法调用上的一致性。 例如,假设一个线程将一个对象排入队列实例中。 如果该队列在线程之间共享,则使该对象排队的队列不能安全地假定它可以稍后使一个对象出队列,或者如果确实使一个队列出队列,则该对象与被排队的对象相同。 如果它希望能够做出这样的假设,则它必须提供范围更广的保护,或者确保它使用的队列实例不被共享。

其他问题围绕着排队对象的突变,即使它们确实是可变的。 它们的状态不受队列及其迭代器同步的保护。

empty()未同步,迭代器方法上的已同步保护了迭代器(可能没有用),但保护了队列本身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM