1/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7package java.util.concurrent;
8
9// BEGIN android-note
10// removed link to collections framework docs
11// END android-note
12
13/**
14 * A {@link BlockingQueue} in which producers may wait for consumers
15 * to receive elements.  A {@code TransferQueue} may be useful for
16 * example in message passing applications in which producers
17 * sometimes (using method {@link #transfer}) await receipt of
18 * elements by consumers invoking {@code take} or {@code poll}, while
19 * at other times enqueue elements (via method {@code put}) without
20 * waiting for receipt.
21 * {@linkplain #tryTransfer(Object) Non-blocking} and
22 * {@linkplain #tryTransfer(Object,long,TimeUnit) time-out} versions of
23 * {@code tryTransfer} are also available.
24 * A {@code TransferQueue} may also be queried, via {@link
25 * #hasWaitingConsumer}, whether there are any threads waiting for
26 * items, which is a converse analogy to a {@code peek} operation.
27 *
28 * <p>Like other blocking queues, a {@code TransferQueue} may be
29 * capacity bounded.  If so, an attempted transfer operation may
30 * initially block waiting for available space, and/or subsequently
31 * block waiting for reception by a consumer.  Note that in a queue
32 * with zero capacity, such as {@link SynchronousQueue}, {@code put}
33 * and {@code transfer} are effectively synonymous.
34 *
35 * @since 1.7
36 * @author Doug Lea
37 * @param <E> the type of elements held in this queue
38 */
39public interface TransferQueue<E> extends BlockingQueue<E> {
40    /**
41     * Transfers the element to a waiting consumer immediately, if possible.
42     *
43     * <p>More precisely, transfers the specified element immediately
44     * if there exists a consumer already waiting to receive it (in
45     * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
46     * otherwise returning {@code false} without enqueuing the element.
47     *
48     * @param e the element to transfer
49     * @return {@code true} if the element was transferred, else
50     *         {@code false}
51     * @throws ClassCastException if the class of the specified element
52     *         prevents it from being added to this queue
53     * @throws NullPointerException if the specified element is null
54     * @throws IllegalArgumentException if some property of the specified
55     *         element prevents it from being added to this queue
56     */
57    boolean tryTransfer(E e);
58
59    /**
60     * Transfers the element to a consumer, waiting if necessary to do so.
61     *
62     * <p>More precisely, transfers the specified element immediately
63     * if there exists a consumer already waiting to receive it (in
64     * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
65     * else waits until the element is received by a consumer.
66     *
67     * @param e the element to transfer
68     * @throws InterruptedException if interrupted while waiting,
69     *         in which case the element is not left enqueued
70     * @throws ClassCastException if the class of the specified element
71     *         prevents it from being added to this queue
72     * @throws NullPointerException if the specified element is null
73     * @throws IllegalArgumentException if some property of the specified
74     *         element prevents it from being added to this queue
75     */
76    void transfer(E e) throws InterruptedException;
77
78    /**
79     * Transfers the element to a consumer if it is possible to do so
80     * before the timeout elapses.
81     *
82     * <p>More precisely, transfers the specified element immediately
83     * if there exists a consumer already waiting to receive it (in
84     * {@link #take} or timed {@link #poll(long,TimeUnit) poll}),
85     * else waits until the element is received by a consumer,
86     * returning {@code false} if the specified wait time elapses
87     * before the element can be transferred.
88     *
89     * @param e the element to transfer
90     * @param timeout how long to wait before giving up, in units of
91     *        {@code unit}
92     * @param unit a {@code TimeUnit} determining how to interpret the
93     *        {@code timeout} parameter
94     * @return {@code true} if successful, or {@code false} if
95     *         the specified waiting time elapses before completion,
96     *         in which case the element is not left enqueued
97     * @throws InterruptedException if interrupted while waiting,
98     *         in which case the element is not left enqueued
99     * @throws ClassCastException if the class of the specified element
100     *         prevents it from being added to this queue
101     * @throws NullPointerException if the specified element is null
102     * @throws IllegalArgumentException if some property of the specified
103     *         element prevents it from being added to this queue
104     */
105    boolean tryTransfer(E e, long timeout, TimeUnit unit)
106        throws InterruptedException;
107
108    /**
109     * Returns {@code true} if there is at least one consumer waiting
110     * to receive an element via {@link #take} or
111     * timed {@link #poll(long,TimeUnit) poll}.
112     * The return value represents a momentary state of affairs.
113     *
114     * @return {@code true} if there is at least one waiting consumer
115     */
116    boolean hasWaitingConsumer();
117
118    /**
119     * Returns an estimate of the number of consumers waiting to
120     * receive elements via {@link #take} or timed
121     * {@link #poll(long,TimeUnit) poll}.  The return value is an
122     * approximation of a momentary state of affairs, that may be
123     * inaccurate if consumers have completed or given up waiting.
124     * The value may be useful for monitoring and heuristics, but
125     * not for synchronization control.  Implementations of this
126     * method are likely to be noticeably slower than those for
127     * {@link #hasWaitingConsumer}.
128     *
129     * @return the number of consumers waiting to receive elements
130     */
131    int getWaitingConsumerCount();
132}
133