NonBlockingQueue.java 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package com.sig.app.common.utils;
  2. import java.util.concurrent.atomic.AtomicInteger;
  3. import java.util.concurrent.atomic.AtomicReference;
  4. public class NonBlockingQueue<T> {
  5. private final AtomicReference<Node<T>> head, tail;
  6. private final AtomicInteger size;
  7. public NonBlockingQueue() {
  8. head = new AtomicReference<>(null);
  9. tail = new AtomicReference<>(null);
  10. size = new AtomicInteger();
  11. size.set(0);
  12. }
  13. public boolean offer(T element) {
  14. if (element == null) {
  15. return false;//throw new NullPointerException();
  16. }
  17. Node<T> node = new Node<>(element);
  18. Node<T> currentTail;
  19. do {
  20. currentTail = tail.get();
  21. node.setPrevious(currentTail);
  22. } while(!tail.compareAndSet(currentTail, node));
  23. if(node.previous != null) {
  24. node.previous.next = node;
  25. }
  26. head.compareAndSet(null, node); //if we are inserting the first element
  27. size.incrementAndGet();
  28. return true;
  29. }
  30. public T take() {
  31. if(head.get() == null) {
  32. return null;
  33. //throw new NoSuchElementException();
  34. }
  35. Node<T> currentHead;
  36. Node<T> nextNode;
  37. do {
  38. currentHead = head.get();
  39. nextNode = currentHead.getNext();
  40. } while(!head.compareAndSet(currentHead, nextNode));
  41. size.decrementAndGet();
  42. return currentHead.getValue();
  43. }
  44. public int size() {
  45. return this.size.get();
  46. }
  47. private class Node<T> {
  48. private final T value;
  49. private volatile Node<T> next;
  50. private volatile Node<T> previous;
  51. public Node(T value) {
  52. this.value = value;
  53. this.next = null;
  54. }
  55. public T getValue() {
  56. return value;
  57. }
  58. public Node<T> getNext() {
  59. return next;
  60. }
  61. public void setPrevious(Node<T> previous) {
  62. this.previous = previous;
  63. }
  64. }
  65. }