Mastering Java Multithreading : Thread Control, Synchronization & Concurrency Utilities

Published: (December 2, 2025 at 04:00 AM EST)
2 min read
Source: Dev.to

Source: Dev.to

Thread Control

Java provides built-in methods to control thread execution.

Key Methods

  • sleep() – pauses the current thread for a given time.
  • join() – waits for another thread to finish.
  • yield() – suggests that the current thread should pause to allow others to execute.

Example

package ayshriv;

public class MasteringBackend {
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(() -> {
            for (int i = 1; i  {
            for (int i = 0; i  {
            for (int i = 0; i  {
            for (int i = 0; i  {
            for (int i = 0; i  {
            try {
                for (int i = 1; i  {
            try {
                for (int i = 1; i  {
    while (true) {
        try {
            System.out.println("Daemon thread working...");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            break;
        }
    }
});
daemon.setDaemon(true);
daemon.start();

When the main (user) thread ends, the JVM will terminate the daemon thread automatically.

Concurrency Utilities

Java’s java.util.concurrent package provides high‑level constructs that simplify multithreaded programming.

ExecutorService

import java.util.concurrent.*;

public class MasteringBackend {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        Callable task = () -> {
            Thread.sleep(500);
            return 42;
        };

        Future future = executor.submit(task);
        System.out.println("Result: " + future.get());

        executor.shutdown();
    }
}

CountDownLatch

import java.util.concurrent.*;

public class MasteringBackend {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);

        Runnable worker = () -> {
            System.out.println(Thread.currentThread().getName() + " working");
            latch.countDown();
        };

        for (int i = 0; i  queue = new ArrayBlockingQueue<>(5);

        Thread producer = new Thread(() -> {
            try {
                queue.put("Message");
                System.out.println("Produced message");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        Thread consumer = new Thread(() -> {
            try {
                String msg = queue.take();
                System.out.println("Consumed: " + msg);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        producer.start();
        consumer.start();

        producer.join();
        consumer.join();
    }
}

These utilities handle thread pooling, synchronization, and inter‑thread data exchange, reducing the need for low‑level synchronized blocks and manual thread management.

Back to Blog

Related posts

Read more »