
Explore the need for stream gatherers to extend Java streams, enabling custom domain-specific operators like moving average, batched processing, and scalable concurrency with virtual threads.
Learn the java stream pipeline from source to terminal operation, including lazy intermediate operators and stateless vs stateful processing, and explore gatherers.
Explore the gather operator in Java streams, implementing the gather interface with initializer, integrator, finisher, and combiner to design stateful, parallelizable pipelines.
Set up a hands-on Maven project for stream gatherer playground, configure JDK 24, add logback in pom.xml, and run Maven sync to download dependencies while organizing sections, packages, and lectures.
Explore how the integrator works with upstream in a stream pipeline by implementing a stateless gatherer integrator, handling downstream push, and controlling upstream flow with a boolean return.
Coordinate the integrator and downstream push booleans to control item flow, where true means more items and false stops. Illustrate short-circuiting and lazy streams.
Review the documented notes for a quick reference to our discussion on stream gatherers and scalable concurrency. Note the current limitation when chaining multiple gatherers, to be discussed later.
Implement a custom gatherer to simulate the filter operator in Java streams using a predicate to pass even elements downstream. Explore parallel streams and the gatherer interface concepts.
Explore the greedy integrator in Java streams, where greedy extends the integrator interface and uses short-circuiting to stop or propagate downstream results.
Demonstrates how the sequential gatherer processes items one by one, using a factory method gatherer of sequential to disable parallel processing and ensure single-thread execution.
Implement flatMap with a gatherer, mapping inputs to streams (1 to AB, 2 to CDE, else empty) and flattening for a 1,2,3 input sequence. Explore backpressure and allMatch-based short-circuit.
Implement take until operator in the Java stream pipeline using a sequential gatherer to emit items until a predicate is satisfied, then stop after the first matching item.
Explore the take until operator by building a generic gatherer that processes a stream, pushes items downstream, and stops when a predicate is met, with a practical retry example.
Discover how the gather operator introduces a gatherer with initializer, integrator, finisher, and combiner to create custom operators in the stream pipeline, driven by the integrator.
Explore stateful custom operators using an object initializer that provides the initial mutable state for sequential gatherers like limit and distinct. Define a combiner to support parallel execution.
Build a simple stateful limit gatherer for streams using an initializer and integrator, a mutable counter, and early stop logic to emit up to the maximum items.
Explore implementing a distinct operator that filters duplicates from a number stream using a set-based state within a gatherer, emitting only unseen items downstream.
Implement a distinct recent gatherer that maintains the last n unique items from an infinite stream using a linked hash set, evicting the oldest when the cache is full.
Learn to build a custom moving average gatherer in Java streams using a sliding window, sum tracking, and a deque for efficient online calculation.
Learn how to build a simple stateful gatherer in modern Java, using a mutable accumulator, an initializer supplier, and an integrator to track counts, with parallel streams.
Learn how finisher, an optional gatherer method, triggers when a stream completes to emit final results or perform cleanup, including batching and flushing incomplete batches.
Demonstrate how the finisher in a buy consumer passes state to the downstream, calls finish, and pushes non-empty batched lists while respecting downstream rejection and batch size limits.
Collect items until a predicate is true with the batch until gatherer, emitting each batch and then restarting, with optional delimiter handling for reading a file line by line.
Explore lazy, breadth-first expansion of hierarchical data using a custom gatherer in a Java stream, starting from a root item and emitting children through a function.
Implement a breadth first expander and gatherer to traverse hierarchical data using a queue, emitting children to a downstream, handling backpressure with integrate and finish methods.
Demonstrate expanding a hierarchical employee structure with the gatherer, streaming direct reports, and mapping to titles to produce a recursive traversal from the CEO root.
Learn how to chain functions in Java, creating combined functions and gatherers to build dynamic stream pipeline operations that adapt at runtime based on user roles.
Highlight the bug with isRejecting in a downstream interface when chaining gatherers, since it defaults to false. Implement a finish method to capture downstream push results.
Explore the combiner for parallel streams, where each thread uses its own state initialized by the supplier, then merges states with a binary operator.
This lecture builds a custom count gatherer to illustrate parallel streams using a combiner, with an items counter state, integrate, and finish to emit the final count.
Explain why splitting work into more subtasks than CPUs improves load balancing and CPU utilization in parallel streams; threads pick up new chunks as they finish, avoiding idle time.
Develop a parallel max gatherer for integer streams that returns the maximum value, optionally using a comparator for genericity, and implement state, an integrator, a combiner, and a finisher.
Implement a top n gatherer for parallel streams that tracks the top n integers using a priority queue, with options for size and comparator, and a merge strategy via combine.
Learn how the top-n gatherer collects a stream of integers, maintains state, and emits the top values with a configurable limit, explaining order implications in parallel streams.
Use a parallel stream only for large cpu-heavy data; avoid for small data or io tasks due to a limited fork join pool; prefer a sequential stream.
Explore Java 24 stream gatherers, including window fixed and window sliding, showing fixed batches of three items for bulk inserts and sliding windows for anomaly detection.
Explore how to use fold with a supplier and by function to apply a stream of transactions to an immutable bank account, producing and logging the final balance.
This lecture introduces scan, a variant of fold that outputs results along the way, using an initial value, with a bank account updating from 100 to 110, 105, and 120.
Learn how map concurrent gatherer uses virtual threads to run IO-bound tasks with controlled concurrency, avoiding parallel for network calls; see a hands-on demo with five and batching.
Learn how parallel processing and the map concurrent gatherer operate in a stream pipeline, processing three items with threads and virtual threads while the main thread coordinates output.
Understand map concurrent behavior and in-order emission in java's virtual threads, even with uneven task durations. Learn why a custom gatherer is needed for first-completed results.
Explore inbuilt gatherers in Java streams, including fixed and sliding windows, fold, and scan. Use map concurrent and virtual threads to run IO tasks while preserving order.
Explore advanced concurrency patterns with stream gatherers using an external services jar, run on port 7070 (modifiable with --serverport 8080), and test product and rating endpoints via swagger.
build a simple external service client in a java project to fetch product and rating data via endpoints, using url, uri, and input stream with try-with-resources, for demo purposes.
Demonstrates using map concurrent to send multiple concurrent product requests, explains maximum concurrency and slot management, and notes order preservation and planned fixes.
Develop a custom gatherer that executes concurrent tasks with an executor service and a completion service, emitting results in the order they complete, ignoring maximum concurrency in phase one.
Explain how an executor completion service processes submitted tasks with a greedy integrate method, using take to retrieve completed futures, and compare shutdown versus shutdown now for canceling pending tasks.
Create a gatherer utility to expose custom gatherers, enabling a sequential gatherer with internal multithreading via execute concurrent. Configure a virtual thread per task executor, greedy integrator, and finish step.
demonstrates executing concurrent tasks with a gatherer, running 1–10, 1–50, and 1–100 tasks, using limit to return first three results and cancel the rest.
Limit the number of concurrent requests by enforcing a maximum concurrency of ten in the gatherer, and emit downstream results to free capacity as task count changes.
Learn to delay errors in a stream gatherer implementation by storing failures and emitting successful results first, implementing a delay error gatherer that tracks futures and pushes to downstream.
Emit next completed result to the downstream, using a delay error gatherer, collect failures in the error list, and throw a consolidated runtime exception with suppressed errors.
Demonstrates a delay error gatherer for concurrent processing, emitting ten responses, then throwing a delayed exception with suppressed errors, and explores behavior under downstream limits and max concurrency.
Adopt a data oriented approach to error handling in Java, using sealed types and pattern matching to return a stream of results with success or failure and avoid exceptions.
Address the nested concurrency problem in building a product aggregate by concurrently fetching product and rating data. Propose an aggregate concurrent gatherer that accepts two functions and a by function.
Solve the nested concurrency aggregate problem by reusing execute concurrent to merge two id-based requests (product and rating) into a single aggregate function, using three parameters and a by function.
Leveraging the gatherer aggregate concurrent, this lecture runs product and rating fetches in parallel, cutting total time from ten to five seconds and handling ranges like 1 to 100.
Clarify how maximum concurrency applies at the task level function, not at the subtask level, with a ten limit.
Learn to handle more subtasks with a generic approach that passes the executor service through the by function. Wrap the executor service to hide it and prevent shutdown.
Design a generic subtask executor and subtask result as wrappers around a future from an executor service to manage nested concurrency in a stream pipeline, with an error handler.
Implement a gatherers util with a generic aggregate concurrent workflow using a subtask executor and by function inputs to run product and rating concurrently.
Explore implementing a timeout pattern in a stream pipeline and examine why a naive integrator fails. The true timeout remains independent of item arrival, exposing issues with declarative approaches.
Shows why a blocking integrator in a stream pipeline makes timeout and other patterns hard to implement, and advocates a shift to asynchronous reactive designs with upstream and downstream consumers.
Learn to build a geo crawler that traverses a hierarchical geo data service and loads all 150,000 world cities into a database using a stream pipeline.
Design a Java stream pipeline using stream gatherers to handle massive io requests, fetch city data concurrently, and batch save results for scalable concurrency.
Set up the geo crawler project using Spring Boot, configure dependencies for an http client and H2 Spring Data JPA, generate the project, and scaffold dto, entity, and repository packages.
Implement a geo data client with endpoints for regions, subregions, country by id, state by id, and city by id, using a generic get method and a rest client.
Configure the Geodata client in the application configuration class, wiring a rest client from a base URL in application.properties and injected by Spring. Enable virtual threads for the http client.
Set up the geo crawler service as a spring component, inject the geo data client and CT repository, and run a request that streams regions and subregions to print IDs.
Optimize geo data retrieval by streaming subregions and countries instead of collecting intermediate results, leveraging the gatherers util execute concurrent to avoid blocking on slow io.
Build a geo crawler service that streams subregions to cities using flatMap and concurrent gatherers, retrieves ten cities, and maps each to a city entity.
Demonstrates streaming 150,000 cities, converting to city entities, then bulk inserting in batches of 1000 with save all. Compares performance of virtual threads vs default configuration.
lower concurrency from the default 1000 to 100 or 50 to fix connection reset errors, testing stability as the host struggles to set up the connection with the external service.
Leverage virtual threads and stream gatherers to tackle large-scale concurrency, improve performance and memory usage, and create reusable gatherers for teams.
Explore next steps after modern Java by comparing microservice communications—gRPC, rsocket, WebFlux, Kafka—and REST/GraphQL, with Redis caching, resilient design, and deployment with Docker and Kubernetes.
Up-to-date with JDK/Java 25 & Spring Boot 4
Prerequisite: Familiarity with Java Virtual Threads is recommended. If you are new to Virtual Threads, consider checking out my companion course on the topic for a solid foundation.
This in-depth course is designed for experienced Java developers looking to master the cutting-edge Stream Gatherers API and unlock the full potential of Virtual Threads for building high-performance, scalable applications.
Java has evolved, and so have its concurrency tools. With the introduction of Stream Gatherers and Virtual Threads, you can now write efficient, readable, and scalable I/O pipelines using familiar Stream constructs. This course is practical, modern, and tailored to help you build real-world, concurrent Java applications without the traditional complexity of thread management.
What You Will Learn
Understand how Stream Gatherers enhance the Java Stream API
Master Stateless Gatherers using integrators for simple yet powerful stream transformations
Build Stateful Gatherers using initializers for scenarios that require shared or evolving context
Implement Finisher logic for end-of-stream aggregation, cleanup, or final state transformation
Explore Combiners and their role in parallel stream execution
Deep-dive into built-in gatherers and learn when and how to use them effectively
Write your own custom gatherers to unlock advanced stream patterns
Use Virtual Threads to handle high-volume I/O-bound tasks with minimal overhead
Design Concurrent Gatherers that:
Execute and emit results
Support Concurrency Limits to avoid resource exhaustion
Handle errors without blocking other operations (e.g. Delay Error pattern)
Allow Nested Concurrent Processing for multi-stage, multi-level pipelines
Build a Massive I/O Stream Pipeline project using Stream Gatherers + Virtual Threads
Ingest 150K+ API calls efficiently with lightweight concurrency
Avoid intermediate collection for better throughput and memory efficiency
Save data with batched writes and stream-friendly persistence
Why Take This Course?
Many developers avoid writing high-concurrency code because of complexity and fear of resource management. This course changes that by using Stream Gatherers and Virtual Threads to simplify the process.
You will learn how to think in terms of composable data pipelines rather than low-level threads or futures. The examples and patterns you build will help you tackle real I/O-heavy use cases with confidence and performance.