How ThreadLocal works in Java

Introduction

Here you will see how ThreadLocal works in Java. Java ThreadLocal class is used to create thread-local variables. The thread-local variable can be read and written by the same thread only.

In multi-threaded environments all threads of an Object share their variables, so if the variable is not thread safe, then an inconsistent state of the variable occurs. Therefore you can use synchronization, but if you want to avoid synchronization, you can use ThreadLocal class to create thread-local variables.

Every thread has its own ThreadLocal variable and it can use its get() and set() methods to get the default value or change its value local to Thread.

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.

Prerequisites

Java 6+

Here is a small example that is showing an use of ThreadLocal class.

TreadLocal

The below class creates ThreadLocal variable that is local to each of the thread.

SimpleDateFormat class is not thread-safe and it cannot be used in multi-threaded environment. Therefore, with the help of ThreadLocal class I am making SimpleDateFormat class thread-safe.

package com.roytuts.threadlocal;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ThreadLocalPerThread {
	// SimpleDateFormat is not thread-safe, so give one to each thread
	private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
		@Override
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
		}
	};
	public static String formatDate(Date date) {
		return formatter.get().format(date);
	}
}

Task Thread

I will create TaskThread class that will format a date. I am formatting the same date through a loop to indicate that each thread will work independently and the ThreadLocal variable is local to a particular thread and will not be visible to other threads.

package com.roytuts.threadlocal;
import java.util.Date;

public class TaskThread implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			System.out.println("Thread: " + Thread.currentThread().getName() + " Formatted Date: "
					+ ThreadLocalPerThread.formatDate(new Date()));
		}
	}
}

Main Class

Create main class to test how the ThreadLocal variable works.

package com.roytuts.threadlocal;

public class ThreadLocalTest {
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread(new TaskThread());
		Thread t2 = new Thread(new TaskThread());
		t1.start();
		t2.start();
	}
}

Testing the Application

When you run the above main class you will see below output:

Thread: Thread-0 Formatted Date: 05-22-2019 10:17:58
Thread: Thread-1 Formatted Date: 05-22-2019 10:17:58
Thread: Thread-1 Formatted Date: 05-22-2019 10:17:58
Thread: Thread-1 Formatted Date: 05-22-2019 10:17:58
Thread: Thread-0 Formatted Date: 05-22-2019 10:17:58
Thread: Thread-0 Formatted Date: 05-22-2019 10:17:58

Notice in the above output, each thread’s value is not visible to other threads.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *