Reputation: 53
As far as I know, In Java, ThreadLocal class enables us to create a virtual thread scope. So a thread can not accesses to another's variable or something else.
Could you please give some piece of code that coder needs to use ThreadLocal and after usage of ThreadLocal everything is ok.
Thanks.
Upvotes: 2
Views: 3667
Reputation: 7828
Just for reference to Yathish Manjunath's answer.
so when a particular Thread add a value to Thread Local object it will insert the current thread's ThreadId as "key" and the Value as "value" in the HashMap.
In Java 8, Thread has a threadLocals
field which is an instance of ThreadLocal.ThreadLocalMap
as for the key for each thread local variable, it's the thread local instance itself.
A snippet taken from the ThreadLocal.java
.
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value); <------ this as the key
else
createMap(t, value);
}
ThreadLocal variable and Thread variable altogether uniquely determine the cached variable: value.
Upvotes: 0
Reputation: 2029
Behind the Scenes, when a ThreadLocal Object is created, it actually creates a HashMap internally, something like below :
HashMap<ThreadID,Value> map;
so when a particular Thread add a value to Thread Local object it will insert the current thread's ThreadId as "key" and the Value as "value" in the HashMap.
map.put(thread.currentthread().getid() , Value );
so again when we fetch the value from the Thread Local object, it will do the below operation :
map.get(thread.currentthread().getid());
so even thought we create ONLY one instance of ThreadLOcal object, but we will be able to make them local to each Thread .
Please check the below piece of code.
we are creating 3 threads by passing the runnable object to it and also we are setting the name of each thread in the constructor itself.
In thr run() method we are setting the ThreadName into the Thread Local object and the thread is put into sleep(), Meanwhile, other thread can enter the run() method and again set its thraedName to the SAME thread Local instance.
Once the Thread is awake, we are fetching the data back from the Thread Local object and printing it...
public class ThreadLocalDemo {
public static void main(String[] args) {
testLocal oneInstance = new testLocal();
Thread A = new Thread(oneInstance);
Thread B = new Thread(oneInstance);
Thread C = new Thread(oneInstance);
A.start();
try
{
Thread.sleep(400);
}
catch(InterruptedException e){}
B.start();
try
{
Thread.sleep(400);
}
catch(InterruptedException e){}
C.start();
try
{
Thread.sleep(400);
}
catch(InterruptedException e){}
}
}
class testLocal implements Runnable
{
private static final ThreadLocal local = new ThreadLocal<String>(){
@Override
protected String initialValue() {
System.out.println(" local thread initialValue() called ");
return "intial Value";
}
};
@Override
public void run() {
local.set(Thread.currentThread().getName());
try
{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.print(Thread.currentThread().getName() + " run() " );
System.out.print(" called.... ");
System.out.println(local.get());
}
}
Upvotes: 2
Reputation: 2257
Using ThreadLocal
is a convenient way of making information available per thread and is commonly used in web applications where the model is one thread per request. The request context data which needs to be tracked separately for each request can be made available using a ThreadLocal
.
ThreadLocal
is commonly used in the Spring Framework, where you have various types of contexts represented by ThreadLocal
depending on the components used.
For real world examples, see:
The intent and implementation in each of these example is similar. e.g. you want to store the Locale
information of a current request and then make it available elsewhere. The set method (e.g. setLocaleContext
will store the information on a ThreadLocal) and the get method (e.g. getLocaleContext
will return the Locale
information from the current request)
Lastly, I'd like to add that abusing ThreadLocal
is not a good idea and it should not be taken as a substitute for a good design. So if the relevant context information can be shared by passing objects with appropriate field values, that should be preferred over ThreadLocal
s which make the information universally accessible. This article may be further useful.
Upvotes: 3
Reputation: 5649
private DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
public String formatFirstDate() {
return df.format(new Date());
}
public String formatSecondDate() {
return df.format(new Date(0));
}
In the above code, if two threads simultaneously call formatFirstDate() and formatSecondDate(), may result in a messed up result since DateFormat object is not thread Safe. This problem can be solved by using Thread Local: -
public static ThreadLocal df = new ThreadLocal() {
protected DateFormat initialValue() {
return new SimpleDateFormat("dd/MM/yyyy");
}
};
public String formatFirstDate() {
return df.get().format(new Date());
}
public String formatSecondDate() {
return df.get().format(new Date(0));
}
Upvotes: 1
Reputation: 300
You can wrap any non-thread safe unit into ThreadLocal to make it thread safe. For example the SimpleDateFormat API of Java which is not thread safe but you can make it thread safe using the following code snippet
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
Upvotes: -1
Reputation: 73528
A somewhat common example is using DateFormat
(or Random
, but it has its own ThreadLocalRandom
class nowadays).
The class is not thread-safe, but it takes time to create a new object every time you need it.
When you create a ThreadLocal<DateFormat>
you can be sure that each thread will have their own DateFormat
they can safely use, and there won't be unnecessary performance hits.
Upvotes: 1