Nas Ahmet
Nas Ahmet

Reputation: 53

An example that shows the requirement of ThreadLocal usage

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

Answers (6)

Hearen
Hearen

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

Yathish Manjunath
Yathish Manjunath

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

vsnyc
vsnyc

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 ThreadLocals which make the information universally accessible. This article may be further useful.

Upvotes: 3

Amit Bhati
Amit Bhati

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

Vineet Tyagi
Vineet Tyagi

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

Kayaman
Kayaman

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

Related Questions