Can Java Threadlocal be applied to a non-static field, if so, how?

ThreadLocal ensures that the field is global and local to the thread. (Global because it is available for all methods in the stream and local, since it is limited only by this stream glass.)

This made no sense to me, since every thread in the stack is limited to that thread only. So this is already "threadlocal", right?

Why do we need ThreadLocal? - Upon further reading, I confirmed my assumption from different sites (most of which are not able to provide these facts or contradict each other) that this is really applicable for static fields . Which makes sense.

So my question is: is there ever a multithreaded scenario where ThreadLocal can / should be applied to non-static fields? (I came across some sites that say that "ThreadLocal" is mainly used for static fields, even https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html uses the word " usually ")

+5
source share
4 answers

There are only local variables in the thread stack. * Static and instance variables live on the heap. If we wanted to, we could just pass ThreadLocal around us without living inside an object or class.

We could view ThreadLocal as a local variable available at any given time.

Ordinary local variables are destroyed when the scope is declared in the returns, but ThreadLocal can live anywhere.

So my question is: is there ever a multithreaded scenario where ThreadLocal can / should be applied to non-static fields?

We can do one ...

 interface Dial {} class Gadget { ThreadLocal<Dial> d = new ThreadLocal<>(); } class Gizmo implements Runnable { Gadget g; Gizmo(Gadget g) { this.g = g; } public void run() {} } { Gadget g = new Gadget(); new Thread(new Gizmo(g)).start(); new Thread(new Gizmo(g)).start(); } 

Both threads have the same Gadget instance, but have their own local Dial .

Why do we need ThreadLocal?

The truth is that we do not need ThreadLocal very often, if at all.


* Only local variables are in the stream stack, with the exception of theoretical JVM optimization, it is allowed to do where objects can be allocated on the stack. We will never know about it if this happens, because it will not be allowed to change the behavior of the program. If an object is shared between threads, it is on the heap.

+3
source

I think this Question is based on a false premise.

ThreadLocal ensures that the field is global and local to the thread. (Global because it is available for all methods in the stream and local, since it is limited only by this stream glass.)

This is not what global really means. Global really means accessible to the entire program without any qualifications. And in fact, Java does not have real global variables. The closest to it is the "public static" fields ... which are available with qualifications.

But back to the Question ...

The threadlocal method is available for the method if two conditions are true:

  • The method call must be in the correct thread. (If it is in a different thread, it sees another variable.)

  • The method should be able to get a ThreadLocal object that effectively "declares" a local thread variable (in any thread).

Does the second condition is that the “declaration” is global?

IMO, no. For two reasons.

  • Global variables in the ordinary sense have only one instance. The local stream has a separate instance for each stream.

  • The fact that ThreadLocal is available for a particular method does not make it available for any method. The usual usage pattern (and good practice) for ThreadLocal is to hold the reference to the object in a private static variable. This means that methods in one class can use the corresponding instances of local thread variables ... but methods in other classes cannot.

Now you can put a link to ThreadLocal in the public static variable, but why are you doing this? You are explicitly creating a missing abstraction ... which can cause problems.

And, of course, you can do what @Radiodef answer shows; those. create a local thread whose instances are available only from methods of a specific instance of a particular class. But it’s hard to understand why you need / need to go to this level of conclusion. (And this can lead to storage leaks ...)


Short answer: if you do not want local thread variables to be available, restrict access to the ThreadLocal object.

+6
source

Threadlocal is a container for a set of variables, each of which is available only to one thread, that is, it provides an instance of the contained class for each thread. Thus, the ThreadLocal object is available globally (permission costs), but each instance of the contained class is only available locally for the thread.

This means that it needs to be initialized and destroyed for each thread in a slightly different way, but in all other ways it matches any other variable.

Note. The point of destroying instances is to prevent memory leaks or state leaks between independent calls on the same thread if threads are retrieved from the pool.

Local thread variables are often used to provide thread safe storage where there is no need for communication between threads. One such example is the definition of a new area in CDI, where this area will exist entirely within the same stream (for example, you could define the area of ​​the asynchronous request).

Thus, it is not necessary to limit it to static or non-stationary variables if it is available where necessary. In the java environment, Static variables are a convenient way to provide this access by default, but in the CDI Singleton bean can provide the same level of access with many advantages.

In the injected singleton case, the singleton bean will contain non-static links to ThreadLocal and provide services for accessing the instances contained in it. Both links to the entered singleton and a singleton link to ThreadLocal will be unsteady.

+2
source
 static ThreadLocal<Whatever> threadLocal; 

Declares a field that points to an instance of the ThreadLocal class. Each thread has a Map<ThreadLocal<?>, Object> , which associates ThreadLocal instances with a value that has the corresponding "local thread variable" for this Thread . That is, each instance of ThreadLocal identifies a "local thread variable", and with respect to the JVM, ThreadLocal is a class like any other.

Usually, when we need a "local thread variable", we only need one, and therefore create only one instance of ThreadLocal , which is often stored in a static field for easy access.

If we need a new “local thread variable” for each instance of the host object, we could simply create a new ThreadLocal instance for each host object and store it in a non-static field. Immediately, I cannot come up with a case where this is the simplest solution, but we could do it.

+2
source

All Articles