Last active
May 14, 2020 04:06
-
-
Save tomtzook/81d7151ab97d05219911a593caca01ab to your computer and use it in GitHub Desktop.
Basic lock-free queue in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.concurrent.atomic.AtomicReference; | |
public class LockFreeQueue<T> { | |
private final AtomicReference<Node<T>> mHead; | |
private final AtomicReference<Node<T>> mLast; | |
public LockFreeQueue() { | |
Node<T> baseNode = new Node<>(null); | |
mHead = new AtomicReference<>(baseNode); | |
mLast = new AtomicReference<>(baseNode); | |
} | |
public void enqueue(T value) { | |
Node<T> node = new Node<>(value); | |
Node<T> lastHead = mHead.get(); | |
while (!mHead.compareAndSet(lastHead, node)) { | |
lastHead = mHead.get(); | |
} | |
node.setNext(lastHead); | |
lastHead.setPrevious(node); | |
} | |
public T dequeue() { | |
Node<T> last = mLast.get(); | |
if (last == mHead.get()) { | |
return null; | |
} | |
Node<T> previous = last.getPrevious(); | |
while (!mLast.compareAndSet(last, previous)) { | |
previous = last.getPrevious(); | |
} | |
previous.setNext(null); | |
return previous.getValue(); | |
} | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
Node<T> node = mHead.get(); | |
Node<T> last = mLast.get(); | |
while (node != last) { | |
builder.append(node); | |
builder.append("->"); | |
node = node.getNext(); | |
} | |
return builder.toString(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Node<T> { | |
private final T mValue; | |
private volatile Node<T> mNext; | |
private volatile Node<T> mPrevious; | |
Node(T value) { | |
mValue = value; | |
} | |
public T getValue() { | |
return mValue; | |
} | |
public Node<T> getNext() { | |
return mNext; | |
} | |
public void setNext(Node<T> next) { | |
mNext = next; | |
} | |
public Node<T> getPrevious() { | |
return mPrevious; | |
} | |
public void setPrevious(Node<T> previous) { | |
mPrevious = previous; | |
} | |
@Override | |
public String toString() { | |
return mValue.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment