<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.17.0</version> </dependency>Note: The Apache Commons Lang3 dependency is included for the
BasicThreadFactory
class,
which provides convenient thread naming and daemon thread configuration.
While Java's built-in Executors.newFixedThreadPool
works without additional dependencies,
using a custom BasicThreadFactory allows better thread management and debugging.import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; import org.apache.commons.lang3.concurrent.BasicThreadFactory; public class MainClass { public static void main(String[] args) throws InterruptedException { final String namingPattern = "_newFixedThreadPool"; // A builder pattern for creating custom thread factories final BasicThreadFactory.Builder builder = new BasicThreadFactory.Builder(); // Creates a thread factory with custom naming pattern and daemon threads // Daemon threads don't prevent JVM shutdown when main program ends final BasicThreadFactory basicThreadFactory = builder.namingPattern(namingPattern).daemon(true).build(); // Creates a fixed thread pool with 2 threads using the custom thread factory final ExecutorService executorService = Executors.newFixedThreadPool(2, basicThreadFactory); // Creates an infinite stream starting from 0, incrementing by 1, and limits the stream to 5 elements (0, 1, 2, 3, 4) // Executes the lambda for each element IntStream.iterate(0, i -> i + 1).limit(5).forEach(t -> executorService.execute(() -> { try { // Pauses current thread execution for specified milliseconds // Random sleep between 1-100ms to simulate varying task durations Thread.sleep(new Random().nextInt(100) + 1); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ": " + t); })); // Blocks until all tasks complete or timeout occurs executorService.awaitTermination(1000l, TimeUnit.MILLISECONDS); // Initiates orderly shutdown where previously submitted tasks are executed but no new tasks will be accepted. // Does not wait for tasks to complete. executorService.shutdown(); } }Output:
_newFixedThreadPool: 1 _newFixedThreadPool: 0 _newFixedThreadPool: 2 _newFixedThreadPool: 4 _newFixedThreadPool: 3Since only 2 threads are available but 5 tasks are submitted, tasks will be queued and executed as threads become available. The random sleep times cause tasks to complete in unpredictable order, which is why the output numbers may not be sequential (1, 0, 2, 4, 3).