Interface AsyncChannel<T>
- Type Parameters:
T- the payload type
- All Superinterfaces:
Iterable<T>
- All Known Implementing Classes:
DefaultAsyncChannel
A channel coordinates producers and consumers without exposing explicit locks or shared mutable state, following the CSP (Communicating Sequential Processes) paradigm popularized by Go's channels.
Channels support both unbuffered (rendezvous) and buffered modes:
- Unbuffered —
create()orcreate(0). Eachsendsuspends until a matchingreceivearrives. - Buffered —
create(n). Values are enqueued until the buffer fills, then senders suspend.
Channels implement Iterable, so they work with for await
and regular for loops — iteration yields received values until the
channel is closed and drained:
def ch = AsyncChannel.create(2)
async { ch.send('a'); ch.send('b'); ch.close() }
for await (item in ch) {
println item // prints 'a', then 'b'
}
- Since:
- 6.0.0
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic AsyncChannel<Instant>after(long millis) Creates a timer channel: a capacity-1 channel that delivers a single value, theInstantat which it fired, oncemillishas elapsed from this call, and then closes.static AsyncChannel<Instant>Creates a timer channel that fires oncedurationhas elapsed; seeafter(long).booleanclose()Closes this channel.static <T> AsyncChannel<T>create()Creates an unbuffered (rendezvous) channel.static <T> AsyncChannel<T>create(int capacity) Creates a channel with the specified buffer capacity.default AsyncChannel<T>Returns a new channel that passes only elements matching the predicate.intReturns the number of values currently buffered.intReturns this channel's buffer capacity.booleanisClosed()Returnstrueif this channel has been closed.default <R> AsyncChannel<R>Returns a new channel that transforms each element using the function.default AsyncChannel<T>merge(AsyncChannel<? extends T> other) Returns a new channel that receives values from both this channel and the other channel.receive()Receives the next value from this channel.Sends a value through this channel.default List<AsyncChannel<T>>Returns two new channels: elements matching the predicate go to the first, non-matching to the second.default AsyncChannel<T>tap(AsyncChannel<T> tap) Returns a new channel that receives all values from this channel while also sending a copy of each value to the tap channel.Methods inherited from interface java.lang.Iterable
forEach, iterator, spliterator
-
Method Details
-
create
Creates an unbuffered (rendezvous) channel. -
create
Creates a channel with the specified buffer capacity.- Parameters:
capacity- the maximum buffer size; 0 for unbuffered
-
after
Creates a timer channel: a capacity-1 channel that delivers a single value, theInstantat which it fired, oncemillishas elapsed from this call, and then closes.Its purpose is to make a deadline a branch of a
ChannelSelect, the way Go'stime.Afterdoes, rather than an exception thrown around the whole select byAwaitable.orTimeout(long, TimeUnit):
As a channel, a timer composes with everything a select offers: several timers give per-branch deadlines, a timer may be guarded withdef result = await ChannelSelect.from(work, AsyncChannel.after(100)).select() if (result.index == 1) { // timed out: result.value is the Instant the timer fired }ChannelSelect.Offer.when(java.util.function.BooleanSupplier), andChannelSelect.fair()andChannelSelect.random()treat it like any other ready branch.The clock starts now, not at the first receive, so a timer created once and reused across selects is a fixed deadline shared by every round. For a per-round timeout that re-arms on each call of a select that is held and reused, use the timer offer
ChannelSelect.after(long)instead. A timer that loses a select keeps its value: it fires all the same and holds the instant until received. Once the value has been taken, further receives fail withChannelClosedExceptionrather than waiting forever, andisClosed()reports that the timer has fired. Closing a timer before it fires cancels it. A delay that is not positive has already elapsed, so the channel is returned already holding its instant: it is ready at once, which suits a deadline computed from an absolute time that has already passed.- Parameters:
millis- how long to wait before firing, in milliseconds- Returns:
- a channel that delivers the firing instant and then closes
- Since:
- 6.0.0
- See Also:
-
after
Creates a timer channel that fires oncedurationhas elapsed; seeafter(long).- Parameters:
duration- how long to wait before firing- Returns:
- a channel that delivers the firing instant and then closes
- Throws:
NullPointerException- if duration is null- Since:
- 6.0.0
-
getCapacity
int getCapacity()Returns this channel's buffer capacity. -
getBufferedSize
int getBufferedSize()Returns the number of values currently buffered. -
isClosed
boolean isClosed()Returnstrueif this channel has been closed. -
send
Sends a value through this channel.The returned
Awaitablecompletes when the value has been delivered to a receiver or buffered. Sending to a closed channel fails immediately withChannelClosedException.- Parameters:
value- the value to send; must not benull- Returns:
- an Awaitable that completes when the send succeeds
- Throws:
NullPointerException- if value is null
-
receive
Receives the next value from this channel.The returned
Awaitablecompletes when a value is available. Receiving from a closed, empty channel fails withChannelClosedException.- Returns:
- an Awaitable that yields the next value
-
close
boolean close()Closes this channel. Idempotent.Buffered values remain receivable. Pending senders fail with
ChannelClosedException. After all buffered values are drained, subsequent receives also fail.- Returns:
trueif this call actually closed the channel
-
filter
Returns a new channel that passes only elements matching the predicate.- Parameters:
predicate- the filter function- Returns:
- a new filtered channel
- Since:
- 6.0.0
-
map
Returns a new channel that transforms each element using the function.- Type Parameters:
R- the output element type- Parameters:
transform- the mapping function- Returns:
- a new transformed channel
- Since:
- 6.0.0
-
merge
Returns a new channel that receives values from both this channel and the other channel. Values are interleaved as they arrive. The output closes when both inputs are exhausted.- Parameters:
other- the channel to merge with- Returns:
- a new merged channel
- Since:
- 6.0.0
-
split
Returns two new channels: elements matching the predicate go to the first, non-matching to the second. Both are closed when this channel is exhausted.- Parameters:
predicate- the split condition- Returns:
- a list of two channels: [matching, non-matching]
- Since:
- 6.0.0
-
tap
Returns a new channel that receives all values from this channel while also sending a copy of each value to the tap channel. Useful for logging, monitoring, or forking a side pipeline.- Parameters:
tap- the channel to send copies to- Returns:
- a new pass-through channel
- Since:
- 6.0.0
-