Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
ThreadLocal | Multithreading Best Practices
Multithreading in Java
course content

Course Content

Multithreading in Java

Multithreading in Java

1. Multithreading Basics
2. Synchronized Collections
3. High-level Synchronization Mechanisms
4. Multithreading Best Practices

bookThreadLocal

ThreadLocal enables you to avoid multithreading-related mechanisms like synchronization, as data from ThreadLocal is accessible only within a single thread.

Imagine a banking application where each client has their own account. If multiple clients are using the application simultaneously, their accounts should remain separate. By using ThreadLocal, each thread (client) gets its own instance of data (account), ensuring that it does not interfere with other threads.

How to use ThreadLocal

ThreadLocal provides a get() method and a set() method, which are self-explanatory.

get() - retrieves the value from the ThreadLocal variable.

set() - set the value to ThreadLocal variable.

Let's create a program to compare a simple variable with ThreadLocal.

Each thread will have its own distinct threadLocalCounter, while the sharedCounter value will be changed and shared among all threads. The program's output will demonstrate that threadLocalCounter values are unique for each thread, whereas sharedCounter will reflect a common result for all threads, which might vary depending on the order in which the threads execute.

java

ThreadLocalComparison

java

CounterTask

copy
12345678910111213141516
public class ThreadLocalComparison { public static void main(String[] args) { CounterTask counterTask = new CounterTask(); // Create threads for demonstrating the behavior Thread thread1 = new Thread(counterTask); Thread thread2 = new Thread(counterTask); Thread thread3 = new Thread(counterTask); // Start the threads thread1.start(); thread2.start(); thread3.start(); } }

And after this program works for us, we get the result:

As you can see, the sharedCounter variable is incremented across different threads, whereas the threadLocalCounter variable maintains the same value in each thread, because each thread has its own threadLocalCounter instance that is independent of other threads.

As you might have observed, the code includes a static method ThreadLocal.withInitial() that sets an initial value for the variable when it is created.

The remove() method in the ThreadLocal class is used to remove the value associated with the current thread.

java

ThreadLocalTask

java

ThreadLocalRemoveExample

copy
123456789101112131415161718192021
class ThreadLocalTask implements Runnable { // Define a `ThreadLocal` variable with an initial value private static ThreadLocal<String> threadLocalValue = new ThreadLocal<>(); @Override public void run() { // Set a value in the `ThreadLocal` for this thread String threadName = Thread.currentThread().getName(); threadLocalValue.set(threadName + " Value"); // Print the current value System.out.println(threadName + " - ThreadLocal Value before removal: " + threadLocalValue.get()); // Remove the value associated with the current thread threadLocalValue.remove(); // Print the value after removal System.out.println(threadName + " - ThreadLocal Value after removal: " + threadLocalValue.get()); } }

As a result of the program execution:

The program assigns a unique value to ThreadLocal for each thread and displays this value before and after the remove() method is invoked. After removing the value with remove(), ThreadLocal returns null on subsequent calls to get().

Note

Data that are in ThreadLocal are not deleted themselves and they must be explicitly deleted!

Why do I Need to Free a Value?

Releasing a value is crucial to prevent memory leaks. ThreadLocal keeps values linked to threads in a special map that is bound to threads. If a value is not removed, it stays in the map even after the thread's usage is complete, leading to unnecessary objects remaining in memory and ultimately resulting in memory leaks.

1. What is the main problem that using ThreadLocal solves?
2. What is the initial value of a ThreadLocal variable when it is created using the withInitial() method?
3. What happens if you do not call the remove() method for a ThreadLocal variable in long-lived threads?
What is the main problem that using ThreadLocal solves?

What is the main problem that using ThreadLocal solves?

Select the correct answer

What is the initial value of a ThreadLocal variable when it is created using the withInitial() method?

What is the initial value of a ThreadLocal variable when it is created using the withInitial() method?

Select the correct answer

What happens if you do not call the remove() method for a ThreadLocal variable in long-lived threads?

What happens if you do not call the remove() method for a ThreadLocal variable in long-lived threads?

Select the correct answer

Everything was clear?

How can we improve it?

Thanks for your feedback!

Section 4. Chapter 4
some-alt