/** * {@inheritDoc} <br> * <p> * IMPLEMENTATION NOTES:<br> * Offer is allowed from multiple threads.<br> * Offer allocates a new node and: * <ol> * <li>Swaps it atomically with current producer node (only one producer 'wins') * <li>Sets the new node as the node following from the swapped producer node * </ol> * This works because each producer is guaranteed to 'plant' a new node and link the old node. No 2 * producers can get the same producer node as part of XCHG guarantee. * * @see java.util.Queue#offer(java.lang.Object) */ @Override @SuppressWarnings("unchecked") public final boolean offer(final E e) { Objects.requireNonNull(e, "The offered value 'e' must be non-null"); final LinkedQueueNode<E> nextNode = new LinkedQueueNode<>(e); final LinkedQueueNode<E> prevProducerNode = PRODUCER_NODE_UPDATER.getAndSet(this, nextNode); // Should a producer thread get interrupted here the chain WILL be broken until that thread is resumed // and completes the store in prev.next. prevProducerNode.soNext(nextNode); // StoreStore return true; }
/** * {@inheritDoc} <br> * <p> * IMPLEMENTATION NOTES:<br> * Offer is allowed from multiple threads.<br> * Offer allocates a new node and: * <ol> * <li>Swaps it atomically with current producer node (only one producer 'wins') * <li>Sets the new node as the node following from the swapped producer node * </ol> * This works because each producer is guaranteed to 'plant' a new node and link the old node. No 2 * producers can get the same producer node as part of XCHG guarantee. * * @see java.util.Queue#offer(java.lang.Object) */ @Override @SuppressWarnings("unchecked") public final boolean offer(final E e) { Objects.requireNonNull(e, "The offered value 'e' must be non-null"); final LinkedQueueNode<E> nextNode = new LinkedQueueNode<>(e); final LinkedQueueNode<E> prevProducerNode = PRODUCER_NODE_UPDATER.getAndSet(this, nextNode); // Should a producer thread get interrupted here the chain WILL be broken until that thread is resumed // and completes the store in prev.next. prevProducerNode.soNext(nextNode); // StoreStore return true; }