Circular Queue声称未覆盖的项目将被覆盖

时间:2013-09-15 21:55:56

标签: java queue circular-buffer

class CircularQueue{
    private char q[];
    private int putloc, getloc;

    public CircularQueue(int size){
      q = new char[size+1];
      putloc = getloc = 0;
    }

    public void put (char ch) {
      if (putloc+1==getloc | ((putloc ==q.length-1) & (getloc==0))) {
        System.out.println ("Queue is full.");
        return;
      }
      putloc++;
      if(putloc==q.length) putloc = 0;
      q[putloc] = ch;
    }

    public char get() {
      if (getloc == putloc){
        System.out.println("Queue is empty.");
        return (char) 0;
      }

      getloc++;
      if(getloc==q.length) getloc =0;
      return q[getloc];
    }
  }

我不明白队列何时会满员。

如果putloc == q.length-1,它将在数组的末尾 getloc == 0将位于数组的开头 因此,如果put()被调用,它会putloc++并转到q[0]并在那里放置一个值。
他们声称它会覆盖q[0]处的值但是如果getloc == 0那么这意味着它已经从数组的该部分返回了一个值。
q[getloc]会立即跟getloc++ getloc == 0 q[0] get() q[1] {{1}},{{1}}将从{{1}}获取一个值,将该空格留空以放置新值。
因此,下次调用{{1}}时,它将从{{1}}获得一个值。

有人可以解释我的逻辑错误吗?

1 个答案:

答案 0 :(得分:0)

您的声明:“如果getloc == 0那么这意味着它已经从数组的该部分返回了一个值。”问题是这并非总是如此。在put()函数中,条件为if (putloc+1==getloc || ((putloc ==q.length-1) && (getloc==0)))。如果数组已满,但没有人调用过get(),那么((putloc ==q.length-1) && (getloc==0))将等于true,而不会返回任何值。

还有两件事需要解决:

- 使用&&||,而不是&|。两个标记表示布尔运算,一个标记用于位操作 - 写的代码不是线程安全的。如果一个线程称为get()而另一个线程同时称为put(),则getloc和/或putloc将不准确。要解决此问题,我会使用synchronized

public void put (char ch) {
    synchronized(q) {
      if (putloc+1==getloc | ((putloc ==q.length-1) & (getloc==0))) {
        System.out.println ("Queue is full.");
        return;
      }
      putloc++;
      if(putloc==q.length) putloc = 0;
      q[putloc] = ch;
   }
}

public char get() {
  synchronized(q) {
      if (getloc == putloc){
        System.out.println("Queue is empty.");
        return (char) 0;
      }

      getloc++;
      if(getloc==q.length) getloc =0;
      return q[getloc];
  }
}