Reactor
One loop observes readiness and dispatches small handlers when work can proceed.
Reactor and Proactor are foundational patterns behind event-driven and asynchronous IO systems. They become useful when thread-per-request models stop scaling cleanly for high numbers of concurrent IO operations, or when the platform wants one evented coordination model rather than many blocked threads.
A system that handles large numbers of concurrent connections for order events, notifications, streaming updates, or gateway traffic may not want one blocked thread per connection. Event-loop patterns can preserve throughput and reduce context-switch costs when the workload is dominated by waiting on IO readiness or completion.
The Reactor pattern waits for IO readiness events and dispatches handlers when a channel becomes ready. The Proactor pattern starts asynchronous operations and handles completion events after the operation finishes. In practice, Java systems encounter reactor-like behavior in non-blocking server frameworks and proactor-like thinking in asynchronous completion APIs.
These patterns are powerful, but they also demand discipline. Blocking accidentally inside an event loop can collapse throughput. The design only works when the execution model is understood and protected carefully.
One loop observes readiness and dispatches small handlers when work can proceed.
Operations start asynchronously and completion callbacks or futures handle the result later.
Evented systems need tiny handlers, clear offloading rules, and careful blocking boundaries.
| Pattern | Main idea | Typical risk |
|---|---|---|
| Reactor | Dispatch when IO is ready | Blocking too long inside the event handler |
| Proactor | Dispatch when async work completes | Complex callback or completion-flow reasoning |
package org.javaomnibus.gateway;
public final class AsyncQuoteService {
public CompletionStage<ShippingQuote> quote(QuoteRequest request) {
return shippingGateway.fetchQuoteAsync(request)
.thenApply(response -> new ShippingQuote(response.amount(), response.currency()));
}
}