Java : ThreadLocal with Examples

ThreadLocal (Java SE 21 & JDK 21) with Examples.
You will find code examples on most ThreadLocal methods.


Summary

This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.

Class diagram

class SharedTask implements Runnable {
    private final ThreadLocal<Integer> local = ThreadLocal.withInitial(() -> 0);

    @Override
    public void run() {
        try {
            final var count = local.get() + 1;
            final var id = Thread.currentThread().threadId();

            System.out.printf("thread id = %d : count = %d%n", id, count);

            TimeUnit.MILLISECONDS.sleep(100);
            local.set(count);

        } catch (InterruptedException e) {
            System.out.println("InterruptedException!");
        }
    }
}

try (final var executor = Executors.newFixedThreadPool(3)) {

    final var sharedTask = new SharedTask();
    for (int i = 0; i < 9; i++) {
        executor.submit(sharedTask);
    }
}

// Result
// ↓
//thread id = 32 : count = 1
//thread id = 33 : count = 1
//thread id = 34 : count = 1
//thread id = 32 : count = 2
//thread id = 33 : count = 2
//thread id = 34 : count = 2
//thread id = 32 : count = 3
//thread id = 33 : count = 3
//thread id = 34 : count = 3

Constructors

ThreadLocal ()

Creates a thread local variable.

final var local = new ThreadLocal<String>();
System.out.println(local.get()); // null

local.set("abc");
System.out.println(local.get()); // abc
final var local = new ThreadLocal<Integer>();
System.out.println(local.get()); // null

local.set(123);
System.out.println(local.get()); // 123

Methods

T get ()

Returns the value in the current thread's copy of this thread-local variable.

class SharedTask implements Runnable {
    private final ThreadLocal<Integer> local = ThreadLocal.withInitial(() -> 0);

    @Override
    public void run() {
        try {
            final var count = local.get() + 1;
            final var id = Thread.currentThread().threadId();

            System.out.printf("thread id = %d : count = %d%n", id, count);

            TimeUnit.MILLISECONDS.sleep(100);
            local.set(count);

        } catch (InterruptedException e) {
            System.out.println("InterruptedException!");
        }
    }
}

try (final var executor = Executors.newFixedThreadPool(3)) {

    final var sharedTask = new SharedTask();
    for (int i = 0; i < 9; i++) {
        executor.submit(sharedTask);
    }
}

// Result
// ↓
//thread id = 32 : count = 1
//thread id = 33 : count = 1
//thread id = 34 : count = 1
//thread id = 32 : count = 2
//thread id = 33 : count = 2
//thread id = 34 : count = 2
//thread id = 32 : count = 3
//thread id = 33 : count = 3
//thread id = 34 : count = 3

protected T initialValue ()

Returns the current thread's "initial value" for this thread-local variable.

Please see also : withInitial(Supplier<? extends S> supplier)

final var local = new ThreadLocal<String>() {
    @Override
    protected String initialValue() {
        return "abc";
    }
};
System.out.println(local.get()); // abc

local.set("XYZ");
System.out.println(local.get()); // XYZ

void remove ()

Removes the current thread's value for this thread-local variable.

final var local = ThreadLocal.withInitial(() -> "abc");
System.out.println(local.get()); // abc

local.set("XYZ");
System.out.println(local.get()); // XYZ

local.remove();
System.out.println(local.get()); // abc
final var local = new ThreadLocal<Integer>();
System.out.println(local.get()); // null

local.set(123);
System.out.println(local.get()); // 123

local.remove();
System.out.println(local.get()); // null

void set (T value)

Sets the current thread's copy of this thread-local variable to the specified value.

Please see get().

static <S> ThreadLocal<S> withInitial (Supplier<? extends S> supplier)

Creates a thread local variable.

final var local = ThreadLocal.withInitial(() -> "abc");
System.out.println(local.get()); // abc

local.set("XYZ");
System.out.println(local.get()); // XYZ

Related posts

To top of page