24
24
/**
25
25
* An unbounded async multi-producer-single-consumer channel.
26
26
*
27
- * <p>This class provides a channel abstraction that allows multiple senders to place values into
28
- * the channel synchronously, and a single consumer to consume values as they become available
29
- * asynchronously. You can construct an {@link AsyncChannel} with the static methods on {@link
30
- * AsyncChannels}.
31
- *
32
- * <p>This interface represents an <i> unbounded </i> queue, meaning there is no mechanism to notify
27
+ * <p>
28
+ * This class provides a channel abstraction that allows multiple senders to place values into the
29
+ * channel synchronously, and a single consumer to consume values as they become available
30
+ * asynchronously. You can construct an {@link AsyncChannel} with the static methods on
31
+ * {@link AsyncChannels}.
32
+ *
33
+ * <p>
34
+ * This interface represents an <i> unbounded </i> queue, meaning there is no mechanism to notify
33
35
* the sender that the queue is "full" (nor is there a notion of the queue being full to begin
34
36
* with). The channel will continue to accept values as fast as the senders can {@link #send} them,
35
37
* regardless of the rate at which the values are being consumed. If senders produce a lot of values
36
38
* much faster than the consumption rate, it will lead to an out of memory, so users are responsible
37
39
* for enforcing that the channel does not grow too large. If you would like a channel abstraction
38
40
* that provides backpressure, see {@link BoundedAsyncChannel}.
39
41
*
40
- * <p>This channel can be terminated by someone calling {@link #terminate()}, it can be called by
42
+ * <p>
43
+ * This channel can be terminated by someone calling {@link #terminate()}, it can be called by
41
44
* consumers or senders. It is strongly recommended that all instances of this class eventually be
42
- * terminated. Mose terminal operations on {@link AsyncIterator} return {@link
43
- * java.util.concurrent.CompletionStage CompletionStages} that whose stage will not complete until
44
- * the channel is terminated. After the channel is terminated, subsequent {@link #send}s are
45
+ * terminated. Mose terminal operations on {@link AsyncIterator} return
46
+ * {@link java.util.concurrent.CompletionStage CompletionStages} that whose stage will not complete
47
+ * until the channel is terminated. After the channel is terminated, subsequent {@link #send}s are
45
48
* rejected, though consumers of the channel will still receive any values that were sent before the
46
49
* termination.
47
50
*
48
- * <p>Typically you'll want to use a channel when you have some "source" of items, and want to
49
- * consume them asynchronously as the become available. Some examples of sources could be a
50
- * collection of {@link java.util.concurrent.CompletionStage CompletionStages}, bytes off of a
51
- * socket, results produced by dedicated worker threads, etc. Suppose you had scenario where you had
52
- * many threads doing some CPU intensive computation, and you'd send their answers off to some
53
- * server somewhere one at a time.
51
+ * <p>
52
+ * Typically you'll want to use a channel when you have some "source" of items, and want to consume
53
+ * them asynchronously as the become available. Some examples of sources could be a collection of
54
+ * {@link java.util.concurrent.CompletionStage CompletionStages}, bytes off of a socket, results
55
+ * produced by dedicated worker threads, etc. Suppose you had scenario where you had many threads
56
+ * doing some CPU intensive computation, and you'd send their answers off to some server somewhere
57
+ * one at a time.
54
58
*
55
- * <pre>{@code
59
+ * <pre>
60
+ * {@code
56
61
* AsyncChannel<Integer> channel = AsyncChannels.unbounded();
57
62
* for (i = 0; i < numThreads; i++) {
58
63
* // spawn threads that send results to channel
77
82
* // terminate the channel, done computing
78
83
* channel.terminate();
79
84
*
80
- * }</pre>
85
+ * }
86
+ * </pre>
81
87
*
82
- * <p>It is also convenient to use a channel to merge many {@link AsyncIterator}s together. Think if
83
- * we were the destination server in the previous example, and we had many compute servers sending
84
- * us numbers they were computing. If we used {@link AsyncIterator#concat} in the following example,
85
- * we would wait until we got all the work from the first iterator to move onto the next. With a
88
+ * <p>
89
+ * It is also convenient to use a channel to merge many {@link AsyncIterator}s together. Think if we
90
+ * were the destination server in the previous example, and we had many compute servers sending us
91
+ * numbers they were computing. If we used {@link AsyncIterator#concat} in the following example, we
92
+ * would wait until we got all the work from the first iterator to move onto the next. With a
86
93
* channel we process each number as soon as it becomes available.
87
94
*
88
- * <pre>{@code
95
+ * <pre>
96
+ * {@code
89
97
* AsyncIterator<Integer> getNumbersFrom(ServerLocation ip);
90
98
* AsyncChannel channel = AsyncChannels.unbounded();
91
99
* futures = ips.stream()
106
114
* channel
107
115
* .forEach(num -> System.out.println(num))
108
116
* .thenAccept(ig -> System.out.println("finished getting all numbers")));
109
- * }</pre>
117
+ * }
118
+ * </pre>
110
119
*
111
- * <p>A reminder, all topics addressed in the documentation of {@link AsyncIterator} apply to this
120
+ * <p>
121
+ * A reminder, all topics addressed in the documentation of {@link AsyncIterator} apply to this
112
122
* interface as well. Most importantly this means:
113
123
*
114
124
* <ul>
115
- * <li>Consumption of an AsyncIterator is <b> not </b> thread safe
116
- * <li>Lazy methods on AsyncIterator like map/flatMap don't consume anything. Make sure you
117
- * actually use a consumption operation somewhere, otherwise no one will ever read what was
118
- * sent
125
+ * <li>Consumption of an AsyncIterator is <b> not </b> thread safe
126
+ * <li>Lazy methods on AsyncIterator like map/flatMap don't consume anything. Make sure you actually
127
+ * use a consumption operation somewhere, otherwise no one will ever read what was sent
119
128
* </ul>
120
129
*
121
130
* @param <T> The type of the elements in this channel
@@ -126,37 +135,41 @@ public interface AsyncChannel<T> extends AsyncIterator<T> {
126
135
/**
127
136
* Sends a value into this channel that can be consumed via the {@link AsyncIterator} interface.
128
137
*
129
- * <p>This method is thread safe - multiple threads can send values into this channel
130
- * concurrently. This channel is unbounded, so it will continue accept new items immediately and
131
- * store them in memory until they can be consumed. If you are sending work faster than you can
132
- * consume it, this can easily lead to an out of memory condition.
138
+ * <p>
139
+ * This method is thread safe - multiple threads can send values into this channel concurrently.
140
+ * This channel is unbounded, so it will continue accept new items immediately and store them in
141
+ * memory until they can be consumed. If you are sending work faster than you can consume it, this
142
+ * can easily lead to an out of memory condition.
133
143
*
134
144
* @param item the item to be sent into the channel
135
145
* @return true if the item was accepted, false if it was rejected because the channel has already
136
- * been terminated
146
+ * been terminated
137
147
*/
138
148
boolean send (T item );
139
149
140
150
/**
141
151
* Terminates the channel, disabling {@link #send}.
142
152
*
143
- * <p>After the channel is terminated all subsequent sends will be rejected, returning false.
144
- * After the consumer consumes whatever was sent before the terminate, the consumer will receive
145
- * an end of iteration notification.
153
+ * <p>
154
+ * After the channel is terminated all subsequent sends will be rejected, returning false. After
155
+ * the consumer consumes whatever was sent before the terminate, the consumer will receive an end
156
+ * of iteration notification.
146
157
*
147
- * <p>This method is thread-safe, and can be called multiple times. An attempt to terminate after
158
+ * <p>
159
+ * This method is thread-safe, and can be called multiple times. An attempt to terminate after
148
160
* termination has already occurred is a no-op.
149
161
*/
150
162
void terminate ();
151
163
152
164
/**
153
165
* Gets a result from the channel if there is one ready right now.
154
166
*
155
- * <p>This method consumes parts of the channel, so like the consumption methods on {@link
156
- * AsyncIterator}, this method is not thread-safe should be used in a single threaded fashion.
157
- * After {@link #terminate()} is called and all outstanding results are consumed, poll will always
158
- * return empty. This method <b> should not </b> be used if there are null values in the channel.
159
- * <br>
167
+ * <p>
168
+ * This method consumes parts of the channel, so like the consumption methods on
169
+ * {@link AsyncIterator}, this method is not thread-safe should be used in a single threaded
170
+ * fashion. After {@link #terminate()} is called and all outstanding results are consumed, poll
171
+ * will always return empty. This method <b> should not </b> be used if there are null values in
172
+ * the channel. <br>
160
173
* Notice that the channel being closed is indistinguishable from the channel being transiently
161
174
* empty. To discover that no more results will ever be available, you must use the normal means
162
175
* on {@link AsyncIterator}: either calling {@link #nextFuture()} and seeing if the result
@@ -165,7 +178,7 @@ public interface AsyncChannel<T> extends AsyncIterator<T> {
165
178
*
166
179
* @throws NullPointerException if the polled result is null
167
180
* @return a present T value if there was one immediately available in the channel, empty if the
168
- * channel is currently empty
181
+ * channel is currently empty
169
182
*/
170
183
Optional <T > poll ();
171
184
}
0 commit comments