0% found this document useful (0 votes)
4 views4 pages

Java ThreadLocal for Thread Safety

This document discusses how to make code thread-safe using ThreadLocal. It explains that without ThreadLocal, instance variables are shared across threads and not thread-safe. With ThreadLocal, each thread has its own independent copy of the variable. The document shows an example of a counter that is not thread-safe and modifies it to use ThreadLocal so that each thread has its own counter that is incremented independently.

Uploaded by

jitendra99943
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views4 pages

Java ThreadLocal for Thread Safety

This document discusses how to make code thread-safe using ThreadLocal. It explains that without ThreadLocal, instance variables are shared across threads and not thread-safe. With ThreadLocal, each thread has its own independent copy of the variable. The document shows an example of a counter that is not thread-safe and modifies it to use ThreadLocal so that each thread has its own counter that is incremented independently.

Uploaded by

jitendra99943
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

ThreadLocal

This lesson discusses thread local storage

ThreadLocal

Consider the following instance method of a class

void add(int val) {

int count = 5;
count += val;
[Link](val);

Do you think the above method is thread-safe? If multiple threads call this
method, then each executing thread will create a copy of the local
variables on its own thread stack. There would be no shared variables
amongst the threads and the instance method by itself would be thread-
safe.

However, if we moved the count variable out of the method and declared
it as an instance variable then the same code will not be thread-safe.

We can have a copy of an instance (or a class) variable for each thread
that accesses it by declaring the instance variable ThreadLocal. Look at
the thread unsafe code below. If you run it multiple times, you'll see
different results. The count variable is incremented 100 times by 100
threads so in a thread-safe world the final value of the variable should
come out to be 10,000.

import [Link];
class Demonstration {
public static void main( String args[] ) throws Exception{

UnsafeCounter usc = new UnsafeCounter();


Thread[] tasks = new Thread[100];

for (int i = 0; i < 100; i++) {


Thread t = new Thread(() -> {
for (int j = 0; j < 100; j++)
[Link]();
});
tasks[i] = t;
[Link]();
}

for (int i = 0; i < 100; i++) {


tasks[i].join();
}

[Link]([Link]);
}
}

class UnsafeCounter {

// Instance variable
int count = 0;

void increment() {
count = count + 1;
}
}

Now we'll change the code to make the instance variable threadlocal. The
change is:

ThreadLocal<Integer> counter = [Link](() -> 0);

The above code creates a separate and completely independent copy of


the variable counter for every thread that calls the increment() method.
Conceptually, you can think of a ThreadLocal<T> variable as a map that
contains mapping for each thread and its copy of the threadlocal variable
or equivalently a Map<Thread, T>. Though this is not how it is actually
implemented. Furthermore, the thread specific values are stored in the
thread object itself and are eligible for garbage collection once a thread
terminates (if no other references exist to the threadlocal value).
The code below is a fixed version of the unsafe counter. Note that each
thread has its own copy of the counter variable, which is incremented a
100 times. Therefore, each thread increments its own copy of counter a
100 times and that value gets printed for each thread.

ThreadLocal variables get tricky when used with the executor service
(threadpools) since threads don't terminate and are returned to the
threadpool. So any threadlocal variables aren't garbage collected. For
interesting scenarios, please see Quiz#8.

class Demonstration {
public static void main( String args[] ) throws Exception{
UnsafeCounter usc = new UnsafeCounter();
Thread[] tasks = new Thread[100];

for (int i = 0; i < 100; i++) {


Thread t = new Thread(() -> {
for (int j = 0; j < 100; j++)
[Link]();

[Link]([Link]());
});
tasks[i] = t;
[Link]();
}

for (int i = 0; i < 100; i++) {


tasks[i].join();
}

[Link]([Link]());
}
}

class UnsafeCounter {

ThreadLocal<Integer> counter = [Link](() -> 0);

void increment() {
[Link]([Link]() + 1);
}
}

You might also like