12 |
|
* A {@linkplain BlockingQueue blocking queue} in which each |
13 |
|
* <tt>put</tt> must wait for a <tt>take</tt>, and vice versa. A |
14 |
|
* synchronous queue does not have any internal capacity, not even a |
15 |
< |
* capacity of one. You cannot <tt>peek</tt> at a synchronous queue |
15 |
> |
* capacity of one. You cannot <tt>peek</tt> at a synchronous queue |
16 |
|
* because an element is only present when you try to take it; you |
17 |
|
* cannot add an element (using any method) unless another thread is |
18 |
|
* trying to remove it; you cannot iterate as there is nothing to |
57 |
|
This implementation divides actions into two cases for puts: |
58 |
|
|
59 |
|
* An arriving producer that does not already have a waiting consumer |
60 |
< |
creates a node holding item, and then waits for a consumer to take it. |
60 |
> |
creates a node holding item, and then waits for a consumer to take it. |
61 |
|
* An arriving producer that does already have a waiting consumer fills |
62 |
< |
the slot node created by the consumer, and notifies it to continue. |
62 |
> |
the slot node created by the consumer, and notifies it to continue. |
63 |
|
|
64 |
|
And symmetrically, two for takes: |
65 |
|
|
66 |
|
* An arriving consumer that does not already have a waiting producer |
67 |
< |
creates an empty slot node, and then waits for a producer to fill it. |
67 |
> |
creates an empty slot node, and then waits for a producer to fill it. |
68 |
|
* An arriving consumer that does already have a waiting producer takes |
69 |
< |
item from the node created by the producer, and notifies it to continue. |
69 |
> |
item from the node created by the producer, and notifies it to continue. |
70 |
|
|
71 |
|
When a put or take waiting for the actions of its counterpart |
72 |
|
aborts due to interruption or timeout, it marks the node |
157 |
|
return (node == last || node.next != null); |
158 |
|
} |
159 |
|
|
160 |
– |
|
160 |
|
void unlink(Node node) { |
161 |
|
Node p = head; |
162 |
|
Node trail = null; |
221 |
|
} |
222 |
|
} |
223 |
|
|
224 |
< |
/* |
225 |
< |
* Unlink the given node from consumer queue. Called by cancelled |
224 |
> |
/** |
225 |
> |
* Unlinks the given node from consumer queue. Called by cancelled |
226 |
|
* (timeout, interrupt) waiters to avoid garbage retention in the |
227 |
|
* absence of producers. |
228 |
|
*/ |
241 |
|
} |
242 |
|
} |
243 |
|
|
244 |
< |
/* |
245 |
< |
* Unlink the given node from producer queue. Symmetric |
244 |
> |
/** |
245 |
> |
* Unlinks the given node from producer queue. Symmetric |
246 |
|
* to unlinkCancelledConsumer. |
247 |
|
*/ |
248 |
|
private void unlinkCancelledProducer(Node node) { |
386 |
|
/** |
387 |
|
* Adds the specified element to this queue, waiting if necessary for |
388 |
|
* another thread to receive it. |
389 |
< |
* @param e the element to add |
390 |
< |
* @throws InterruptedException if interrupted while waiting. |
391 |
< |
* @throws NullPointerException if the specified element is <tt>null</tt>. |
389 |
> |
* |
390 |
> |
* @throws InterruptedException {@inheritDoc} |
391 |
> |
* @throws NullPointerException {@inheritDoc} |
392 |
|
*/ |
393 |
|
public void put(E e) throws InterruptedException { |
394 |
|
if (e == null) throw new NullPointerException(); |
427 |
|
/** |
428 |
|
* Inserts the specified element into this queue, waiting if necessary |
429 |
|
* up to the specified wait time for another thread to receive it. |
430 |
< |
* @param e the element to add |
431 |
< |
* @param timeout how long to wait before giving up, in units of |
432 |
< |
* <tt>unit</tt> |
433 |
< |
* @param unit a <tt>TimeUnit</tt> determining how to interpret the |
434 |
< |
* <tt>timeout</tt> parameter |
436 |
< |
* @return <tt>true</tt> if successful, or <tt>false</tt> if |
437 |
< |
* the specified waiting time elapses before a consumer appears. |
438 |
< |
* @throws InterruptedException if interrupted while waiting. |
439 |
< |
* @throws NullPointerException if the specified element is <tt>null</tt>. |
430 |
> |
* |
431 |
> |
* @return <tt>true</tt> if successful, or <tt>false</tt> if the |
432 |
> |
* specified waiting time elapses before a consumer appears. |
433 |
> |
* @throws InterruptedException {@inheritDoc} |
434 |
> |
* @throws NullPointerException {@inheritDoc} |
435 |
|
*/ |
436 |
|
public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { |
437 |
|
if (e == null) throw new NullPointerException(); |
472 |
|
/** |
473 |
|
* Retrieves and removes the head of this queue, waiting if necessary |
474 |
|
* for another thread to insert it. |
475 |
< |
* @throws InterruptedException if interrupted while waiting. |
475 |
> |
* |
476 |
|
* @return the head of this queue |
477 |
+ |
* @throws InterruptedException {@inheritDoc} |
478 |
|
*/ |
479 |
|
public E take() throws InterruptedException { |
480 |
|
final ReentrantLock qlock = this.qlock; |
514 |
|
* Retrieves and removes the head of this queue, waiting |
515 |
|
* if necessary up to the specified wait time, for another thread |
516 |
|
* to insert it. |
517 |
< |
* @param timeout how long to wait before giving up, in units of |
522 |
< |
* <tt>unit</tt> |
523 |
< |
* @param unit a <tt>TimeUnit</tt> determining how to interpret the |
524 |
< |
* <tt>timeout</tt> parameter |
517 |
> |
* |
518 |
|
* @return the head of this queue, or <tt>null</tt> if the |
519 |
< |
* specified waiting time elapses before an element is present. |
520 |
< |
* @throws InterruptedException if interrupted while waiting. |
519 |
> |
* specified waiting time elapses before an element is present. |
520 |
> |
* @throws InterruptedException {@inheritDoc} |
521 |
|
*/ |
522 |
|
public E poll(long timeout, TimeUnit unit) throws InterruptedException { |
523 |
|
long nanos = unit.toNanos(timeout); |
559 |
|
|
560 |
|
// Untimed nonblocking versions |
561 |
|
|
562 |
< |
/** |
563 |
< |
* Inserts the specified element into this queue, if another thread is |
564 |
< |
* waiting to receive it. |
565 |
< |
* |
566 |
< |
* @param e the element to add. |
567 |
< |
* @return <tt>true</tt> if it was possible to add the element to |
568 |
< |
* this queue, else <tt>false</tt> |
569 |
< |
* @throws NullPointerException if the specified element is <tt>null</tt>. |
570 |
< |
*/ |
562 |
> |
/** |
563 |
> |
* Inserts the specified element into this queue, if another thread is |
564 |
> |
* waiting to receive it. |
565 |
> |
* |
566 |
> |
* @param e the element to add |
567 |
> |
* @return <tt>true</tt> if it was possible to add the element to |
568 |
> |
* this queue, else <tt>false</tt> |
569 |
> |
* @throws NullPointerException if the specified element is null |
570 |
> |
*/ |
571 |
|
public boolean offer(E e) { |
572 |
|
if (e == null) throw new NullPointerException(); |
573 |
|
final ReentrantLock qlock = this.qlock; |
621 |
|
/** |
622 |
|
* Always returns <tt>true</tt>. |
623 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
624 |
+ |
* |
625 |
|
* @return <tt>true</tt> |
626 |
|
*/ |
627 |
|
public boolean isEmpty() { |
631 |
|
/** |
632 |
|
* Always returns zero. |
633 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
634 |
< |
* @return zero. |
634 |
> |
* |
635 |
> |
* @return zero |
636 |
|
*/ |
637 |
|
public int size() { |
638 |
|
return 0; |
641 |
|
/** |
642 |
|
* Always returns zero. |
643 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
644 |
< |
* @return zero. |
644 |
> |
* |
645 |
> |
* @return zero |
646 |
|
*/ |
647 |
|
public int remainingCapacity() { |
648 |
|
return 0; |
657 |
|
/** |
658 |
|
* Always returns <tt>false</tt>. |
659 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
660 |
+ |
* |
661 |
|
* @param o the element |
662 |
|
* @return <tt>false</tt> |
663 |
|
*/ |
677 |
|
} |
678 |
|
|
679 |
|
/** |
680 |
< |
* Returns <tt>false</tt> unless given collection is empty. |
680 |
> |
* Returns <tt>false</tt> unless the given collection is empty. |
681 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
682 |
+ |
* |
683 |
|
* @param c the collection |
684 |
< |
* @return <tt>false</tt> unless given collection is empty |
684 |
> |
* @return <tt>false</tt> unless the given collection is empty |
685 |
> |
* @throws NullPointerException if the specified collection is null |
686 |
|
*/ |
687 |
|
public boolean containsAll(Collection<?> c) { |
688 |
|
return c.isEmpty(); |
691 |
|
/** |
692 |
|
* Always returns <tt>false</tt>. |
693 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
694 |
+ |
* |
695 |
|
* @param c the collection |
696 |
|
* @return <tt>false</tt> |
697 |
|
*/ |
702 |
|
/** |
703 |
|
* Always returns <tt>false</tt>. |
704 |
|
* A <tt>SynchronousQueue</tt> has no internal capacity. |
705 |
+ |
* |
706 |
|
* @param c the collection |
707 |
|
* @return <tt>false</tt> |
708 |
|
*/ |
714 |
|
* Always returns <tt>null</tt>. |
715 |
|
* A <tt>SynchronousQueue</tt> does not return elements |
716 |
|
* unless actively waited on. |
717 |
+ |
* |
718 |
|
* @return <tt>null</tt> |
719 |
|
*/ |
720 |
|
public E peek() { |
756 |
|
/** |
757 |
|
* Sets the zeroeth element of the specified array to <tt>null</tt> |
758 |
|
* (if the array has non-zero length) and returns it. |
759 |
+ |
* |
760 |
|
* @param a the array |
761 |
|
* @return the specified array |
762 |
+ |
* @throws NullPointerException if the specified array is null |
763 |
|
*/ |
764 |
|
public <T> T[] toArray(T[] a) { |
765 |
|
if (a.length > 0) |
767 |
|
return a; |
768 |
|
} |
769 |
|
|
770 |
< |
|
770 |
> |
/** |
771 |
> |
* @throws UnsupportedOperationException {@inheritDoc} |
772 |
> |
* @throws ClassCastException {@inheritDoc} |
773 |
> |
* @throws NullPointerException {@inheritDoc} |
774 |
> |
* @throws IllegalArgumentException {@inheritDoc} |
775 |
> |
*/ |
776 |
|
public int drainTo(Collection<? super E> c) { |
777 |
|
if (c == null) |
778 |
|
throw new NullPointerException(); |
787 |
|
return n; |
788 |
|
} |
789 |
|
|
790 |
+ |
/** |
791 |
+ |
* @throws UnsupportedOperationException {@inheritDoc} |
792 |
+ |
* @throws ClassCastException {@inheritDoc} |
793 |
+ |
* @throws NullPointerException {@inheritDoc} |
794 |
+ |
* @throws IllegalArgumentException {@inheritDoc} |
795 |
+ |
*/ |
796 |
|
public int drainTo(Collection<? super E> c, int maxElements) { |
797 |
|
if (c == null) |
798 |
|
throw new NullPointerException(); |