Random and Helpers
Beyond the major classes, java.util.concurrent provides several critical utilities for managing concurrent state and results.
ThreadLocalRandom #
ThreadLocalRandom is a random number generator that is isolated to the current thread. It is significantly faster than using a single shared Random instance across multiple threads.
Canonical Usage: Always use ThreadLocalRandom for generating random numbers in multi-threaded applications. It avoids the internal synchronization and contention that slows down java.util.Random when many threads access it.
// Fast, thread-safe random number
int value = ThreadLocalRandom.current().nextInt(1, 101);
ExecutorCompletionService #
ExecutorCompletionService provides a way to submit multiple tasks to an executor and retrieve their results in the order they complete, rather than the order they were submitted.
Canonical Usage: Use CompletionService when you want to “race” several tasks and take the first one that finishes, or when you want to start processing results immediately as they become available.
CompletionService<String> service = new ExecutorCompletionService<>(executor);
// Submit many tasks
service.submit(() -> fetchFromDatabase());
service.submit(() -> fetchFromApi());
// Take the first result that finishes
Future<String> firstResult = service.take(); // Blocks until first completion
String result = firstResult.get();
Difference from invokeAll() #
invokeAll(): Blocks the main thread until all tasks are finished and returns results in the original submission order.CompletionService: Allows you to process results one-by-one as they arrive, maximizing concurrency by starting the next stage of processing as soon as any task is done.