Skip to main content

Command Palette

Search for a command to run...

Java Threads & Concurrency API: Part 2

Updated
2 min read
Java Threads & Concurrency API: Part 2
I
Welcome to Bits8Byte! I’m Ish, an AI Engineer with 11+ years of experience across software engineering, automation, cloud, and AI-driven systems. This blog is where I share practical insights, technical deep dives, and real-world lessons from building modern software and exploring the fast-moving world of AI. My background spans Java, Spring Boot, Python, FastAPI, AWS, Docker, Kubernetes, DevOps, observability, and automation. Today, my work is increasingly focused on AI engineering, including LLM applications, AI agents, production-grade microservices, and scalable cloud-native architectures. Here, you’ll find thoughtful writing on AI trends, engineering best practices, software architecture, and the mindset required to adapt and grow in the age of AI. My aim is not just to explain technology, but to make it useful, practical, and grounded in real implementation experience. Thanks for stopping by. I hope this space helps you learn something valuable, think more deeply, and stay ahead in a rapidly evolving industry.

ExecutorService

Creating Threads with ExecutorService

In Part I of this article, we discussed what threads are in Java, how to create them, the concept of a task, and the differences between using the Callable and Runnable interfaces.

Let's delve a bit deeper into the Concurrency API, where Java introduced the ExecutorService, which assists us in creating and managing threads.

ExecutorService is an interface in Java. To create an instance and utilize this interface, the Concurrency API offers a factory class called "Executors."

Single-Thread Executor

  • Create an ExecutorService interface reference variable.

  • Initialize it using Executors class. Let us use the simplest one → newSingleThreadExecutor().

  • Create a task using Runnable and pass it to a method called on the instance created in the above step.

Using Single Thread Executor

Output:

Task is smallest unit of work performed by a Thread
Second task
ExecutorService - Main
Third task

You can see that all the tasks using a single thread executor are in order, whereas the one by the Main thread follows no sequence as it’s a separate thread. Hence, results are guaranteed to be executed in the order in which they are added to the executor service (for single thread executor).

But…this guarantee vanishes when the number of threads increases so it’s better not to code relying on this behavior.

Shutting Down a Thread Executor

Executor thread creates a non-daemon thread and hence it is important to call shutdown() method once you are finished using the service.

It doesn't implement AutoCloseable interface so we cannot use it with try-with-resources either.

Executor Service Lifecycle

Note: In the next article we will see how to use submit() instead of execute() and the advantage of doing so.


Dear Readers,

I hope you are enjoying the content I provide on my blog. As a passionate writer and dedicated software developer, I strive to create valuable and informative articles that resonate with you. Today, I would like to extend an invitation to support my work and help me continue producing high-quality content.

I have set up a Buy Me a Coffee page, a platform that allows readers like you to show their appreciation by making a small donation. Your contribution, no matter how big or small, goes a long way in supporting my efforts and keeping the blog running. You can also sponsor using the links at the bottom of this page.