Just wrote an Evicting Queue implementation, as an ordinary Linked List working under the hood, in Java; which, I hope, I've made thread safe, could you review?
Code:
package com.threadsafedatastructs.EvictingQueue;
import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
public class EvictingQueue<T> {
private final int MAX_SIZE;
private List<T> data = new LinkedList<>();
private volatile T o;
private volatile ArrayDeque<T> dequeO;
public EvictingQueue(int _maxSize) {
this.MAX_SIZE = _maxSize;
}
public synchronized boolean isEmpty() {
return data.isEmpty();
}
public synchronized int size() {
return data.size();
}
public T head() { /* Peek the first element */
return this.data.get(0);
}
public T tail() { /* Peek the last element */
return this.data.get(this.data.size() - 1);
}
public synchronized T popFirst() {
if (!this.data.isEmpty()) {
o = data.remove(0);
notifyAll();
return o;
}
throw new NoSuchElementException();
}
public synchronized T popLast() {
if (!this.data.isEmpty()) {
o = data.remove(data.size() - 1);
notifyAll();
return o;
}
throw new NoSuchElementException();
}
public synchronized boolean push(T item) {
if (this.data.size() <= MAX_SIZE) {
if (this.data.size() == MAX_SIZE) {
this.popFirst();
this.data.add(0, item);
notifyAll();
return true;
}
this.data.add(0, item);
notifyAll();
return true;
}
throw new IndexOutOfBoundsException();
}
public synchronized boolean append(T item) {
if (this.data.size() <= MAX_SIZE) {
if (this.data.size() == MAX_SIZE) {
this.popFirst();
boolean obj = this.data.add(item);
notifyAll();
return obj;
}
boolean obj = this.data.add(item);
notifyAll();
return obj;
}
throw new IndexOutOfBoundsException();
}
public synchronized ArrayDeque<T> pollAll() {
dequeO = new ArrayDeque<>(this.data);
this.data.clear();
notifyAll();
return dequeO;
}
@Override
public String toString() {
return data.toString();
}
public int getMAX_SIZE() {
return MAX_SIZE;
}
}
I'm interested in that volatile
variables, are they necessary? Or maybe I should add more? notifyAll()
do those synchronized methods need this call?
Also, this: if (this.data.size() <= MAX_SIZE)
condition seems redundant, because list data
shouldn't be longer than 100 anyway; but this is the simplest way for me to limit Linked List length in Java (also, may help with tests).