Live coding puzzles question 178 of 180 senior
Write a non-blocking stack.
Collections.synchronizedListwith add and remove at the end- Correct: An
AtomicReferenceto the head node, with push and pop in CAS retry loops - A
ConcurrentLinkedDequewith a lock - An
AtomicIntegerindex into an array
class Stack<T> {
private record Node<T>(T value, Node<T> next) { }
private final AtomicReference<Node<T>> head = new AtomicReference<>();
void push(T value) {
Node<T> oldHead;
Node<T> newHead;
do {
oldHead = head.get();
newHead = new Node<>(value, oldHead);
} while (!head.compareAndSet(oldHead, newHead));
}
T pop() {
Node<T> oldHead;
Node<T> newHead;
do {
oldHead = head.get();
if (oldHead == null) {
return null;
}
newHead = oldHead.next();
} while (!head.compareAndSet(oldHead, newHead));
return oldHead.value();
}
}
Then discuss what you would be asked next: this is lock-free but not wait-free; under heavy contention the retry loop wastes work, so a real implementation backs off; and in a language without a garbage collector this is the textbook ABA hazard, which is why C++ needs hazard pointers and Java does not.