How to use MDC with thread pools in Java?

Better Stack Team
Updated on August 25, 2023

In Java, MDC (Mapped Diagnostic Context) is a feature provided by logging frameworks like Log4j and Logback. It allows you to associate key-value pairs with the current thread's execution context, which can be very useful in multi-threaded environments, including scenarios involving thread pools.

Using MDC with thread pools involves setting and clearing MDC values appropriately before and after executing tasks in the thread pool. This ensures that each task executed by a thread in the pool has its specific MDC values, preventing interference between threads.

Here's how you can use MDC with thread pools in Java:

1. Initialize MDC values before submitting tasks to the thread pool

Before submitting tasks to the thread pool, set the MDC values that you want to associate with the executing threads. For example:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class Task implements Runnable {
    private static final Logger LOGGER = LoggerFactory.getLogger(Task.class);

    private String requestId;

    public Task(String requestId) {
        this.requestId = requestId;

    public void run() {
        // Set MDC values for the current thread
        MDC.put("requestId", requestId);

        // Perform your task logic"Processing request: {}", requestId);

        // Clear MDC values to avoid interference with other tasks

2. Submit tasks to the thread pool

Once you have the tasks created with their associated MDC values, you can submit them to the thread pool for execution. Make sure to use an appropriate thread pool implementation, such as ExecutorService, to manage the threads.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
    public static void main(String[] args) {
        // Create a thread pool with a fixed number of threads
        int numThreads = 5;
        ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);

        // Submit tasks with different requestId values
        for (int i = 1; i <= 10; i++) {
            String requestId = "REQ_" + i;
            threadPool.submit(new Task(requestId));

        // Shutdown the thread pool when no more tasks need to be submitted

In this example, we are creating a thread pool with five threads and submitting ten tasks, each with a different requestId. The Task class sets the requestId as an MDC value for the current thread and logs the processing of each request. After the task is completed, we clear the MDC values to prevent interference with other tasks.

By using MDC with thread pools, you can ensure that each task in the pool has its specific MDC values, providing a better context for log messages and easier debugging in multi-threaded applications.

To learn more about logging, visit Better Stack Community.

Got an article suggestion? Let us know
Explore more
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

We are hiring.

Software is our way of making the world a tiny bit better. We build tools for the makers of tomorrow.

Explore all positions →