When leveraging parallel processing of an event stream, it is often desirable to partition data along a particular piece of metadata referred to as a "key" upon which message orders can be guaranteed for a given key value. This same pattern can be extended down to individual consumer processes which may leverage multi-threaded processing within.
In Java, the JDK provides the ExecutorService
API for simplifying the task of running asynchronous code. A service instance can be created with a specified number of threads which then receives tasks which will be executed in parallel on one of these threads:
ExcecutorService executor = Executors.newFixedThreadPool(8); // allow up to 8 tasks to execute concurrently