I wrote it this just for learning. Is there holes at this code?
public interface ConcurrentStack<T> {
//blocking
void put(T t) throws InterruptedException;
//blocking
T poll() throws InterruptedException;
//non-blocking put
boolean offer(T t);
//non-blocking get
T take();
}
class ConcurrentStackImpl<T> implements ConcurrentStack<T> {
private volatile AtomicBoolean locked = new AtomicBoolean(false);
private List<T> internalList = new ArrayList<T>();
private final int maxSize; // this final mandatory? I am afraid about visibility
public ConcurrentStackImpl(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException();
}
this.maxSize = maxSize;
}
@Override //blocking
public void put(T t) throws InterruptedException {
while (!locked.compareAndSet(false, true)) ;//busy waiting
internalList.add(t);
locked.set(false);
}
@Override // non-blocking
public T poll() throws InterruptedException {
while (!locked.compareAndSet(false, true)) ;//busy waiting
T value = internalList.get(internalList.size() - 1);
locked.set(false);
return value;
}
@Override
public boolean offer(T t) {
if (locked.compareAndSet(false, true)) {
if (internalList.size() >= maxSize) {
return false;
}
boolean addResult = internalList.add(t);
locked.set(false);
return addResult;
}
return false;
}
@Override
public T take() {
if (locked.compareAndSet(false, true)) {
T t = internalList.get(internalList.size() - 1);
locked.set(false);
return t;
}
return null;
}
}