Can we get back reference to a member variable of a Thread like the way we get for ThreadLocal?
For example, lets say we use a counter variable to counter amount of requests processed by the Thread in a ThreadLocal variable. Consider that we are using a ThreadPool Executer for reusing threads. Now every Thread keeps a reference to a ThreadLocal counter variable and it can increment its own copy after every request.
In a similar manner if i have a Member variable inside a Runnable, can i get back a reference to it? The Thread is anyway being reused.
if i have a Member variable inside a Runnable, can i get back a reference to it?
When you say "a Runnable", you're talking about some object that implements the Runnable interface. There is nothing magic about Runnable and there is nothing magic about a run() method.
The member variables of your Runnable object are just like the member variables of any other object, and your code accesses them in the same way.
P.S., Usually, when you see ThreadLocal in a program, it means
The program used to be single-threaded,
It keeps a lot of its state in static variables,
Somebody added multi-threading as an after-thought, and
It makes sense for some of that static state to be duplicated for each thread.
I would almost never use ThreadLocal in a new program, because I try hard not to write any code that depends on static variables, and if you're using ThreadLocal for non-static data, you're probably making your program way more complicated than it needs to be.
Related
I am running into this particular issue and was wondering if anyone has come across this particular issue. I have a method: methodA() - this will create a ThreadLocal called "temp" if it doesn't exist, if the ThreadLocal exists, it'll return that ThreadLocal variable (IE: "temp" in this scenario)
Basically the scenario I am running into is this: I call methodA() - (I create the ThreadLocal variable "old_temp") Then I call the method:
CompletableFuture.supplyAsync( () ->{ThreadContext.put("RequestId", requestId); methodB();}, iotaInvokerService).handleAsync(methodC());
Where methodB() is from another team's library and methodB() invokes methodA().
When methodB() invokes methodA(), I want methodA() to return the ThreadLocal variable "old_temp" that was initially created when methodA() was first called. However, when methodB() invokes methodA(), instead of returning the "old_temp" ThreadLocal variable, it creates a completely new ThreadLocal variable to use, which I do not want. When methodB() invokes methodA(), I want it to return "old_temp". Could anyone be able to help me with this scenario?
IE, my belief is that when CompletableFuture.supplyAsync is called with an executorService, it creates a new Thread to which the ThreadLocal variables context are not passed on, which seems to be the problem.
I saw Propagating ThreadLocal to a new Thread fetched from a ExecutorService but I still wasn't sure/still confused on how to apply it to my scenario. I think the thing is that I know what ThreadLocal variable is it that I want, but I am not too sure.
ThreadLocal provides thread-local variables in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. If a computation is started by a thread and continued by another one, then using ThreadLocal seams inappropriate.
If you rely on a library like project reactor, then you can use a Context that is automatically is propagated...
Another option is to use global values (or a singleton that allow access to ...)
something about static:
instances of class share static method
the similar questions:
Java: when to use static methods
What does the 'static' keyword do in a class?
I am confusing about:
static method just have only one memory block?
if i use static method in multithreading, will it block?
I am confusing about:
static method just have only one memory block? if i use static method
in multithreading, will it block?
The static keyword in Java simply means "without regard or knowledge of any particular instance of an object."
An instance method can use this to access the fields of its associated instance, but a static method has no associated instance and so this makes no sense.
In multithreading, thread safety involves protecting the consistency and integrity of mutable data. Because objects encapsulate the state of their instance fields, instance methods only need to be concerned about thread safety in those circumstances in which more than one thread will be accessing the same object.
So while thread confinement of an object is a valid thread safety policy for instances of a class, this same reasoning is invalid for static methods because they have no instance.
This has nothing to do with memory blocks at all. It just has to do with access. An object instance is accessed through a reference. If the reference is thread confined, then the object to which that reference points will always be thread safe. But any thread anywhere that can access your class can potentially get to its static members because no reference to an instance is needed to use them.
Static methods are non-blocking by default. You can implement your own synchronization/thread safety policy and have your static method block if you wish.
Each thread has its own stack space, each time a thread calls a method (static or virtual) that call allocates a stack frame, which holds local variables. nothing about this is specific to static methods.
Static methods can be called concurrently by multiple threads, unless you specifically do something to thwart that, such as requiring that the caller acquire a lock (such as using the synchronized keyword).
Static methods are good for cases where there is no shared state. They may be ok in cases accessing or modifying threadsafe shared state, depending on what level of concurrency is needed and how efficient the threadsafe things being accessed are.
Look out for bottlenecks. Putting the synchronized keyword on a static method may be a problem as that limits your application to calling it with only one thread at a time. Alternative strategies including using atomic objects, using threadsafe data structures designed for high concurrency, or using thread confinement may be preferable to locking.
static method just have only one memory block?
No, methods don't have memory blocks. Threads executing those methods do. Each thread will have it's own memory on the stack where it stores all the method arguments and variables.
if i use static method in multithreading, will it block
A thread cannot access the memory of another thread, but if there is some resource that belongs to all instances and is supposed to be accessed sequentially, then you can synchronize or lock the static method, thus making it a blocking one. Otherwise, no.
Even though there is one instance of a static method, each thread gets its own stack-frame, which means each thread can exercise the same method but in a separate "world" from other threads.
Threads always get their own stack, even for a singleton class (one instance):
so, when to use static methods and when to not?
The main reason for not using static methods everywhere is that they are difficult to unit-test barring manipulating compiled code (Powermock), so static methods should have no dependencies that would require mocking, i.e. the test calls the real method with an input and asserts the output, verbatim, in two steps.
Non-static methods allow you to isolate your test solely to that method by stubbing, mocking, or spying on objects that the method depends on.
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This made little sense to me as each thread's stack is confined to that thread alone. So it is already 'threadlocal', right ?
Why then do we need ThreadLocal ? - On further reading, I confirmed my assumption from various sites (a majority of which fail to provide these facts or contradict each other) that this is indeed applicable for static fields.
Which does make sense.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields ? (I came across some sites that say 'ThreadLocal' is "mainly" used for static fields; even https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html uses the word "typically")
I think that this Question is based on a false premise.
ThreadLocal ensures a field is global and local to a thread. (Global because it is available to all methods in the thread and local because it is confined to that thread's stack alone.)
This is not what "global" really means. Global really means accessible to the entire program without any qualification. And in fact, Java doesn't have true global variables. The closest it has is "public static" fields ... which are accessible with qualification.
But back to the Question ...
A threadlocal variable is available to a method if two conditions are satisfied:
The method call must be on the correct thread. (If it is on a different thread, it sees a different variable.)
The method must be able to get hold of the ThreadLocal object that effectively "declares" the thread local variable (in any thread).
Does the 2nd condition imply that the "declaration" is global?
IMO, no. For two reasons.
Global variables in the conventional sense have only one instance. A thread local has a distinct instance for each thread.
The fact that the ThreadLocal is accessible to a specific method does not make it accessible to any method. The normal (and good practice) usage pattern for a ThreadLocal is to hold the object reference in a private static variable. That means that methods in the same class can use the corresponding thread local variable instances ... but methods in other classes can't.
Now it is possible to put the reference to ThreadLocal in a public static variable, but why would you do that? You are explicitly creating a leaky abstraction ... which is liable to cause problems.
And of course, you can do what #Radiodef's answer shows; i.e. create a thread local whose instances are only accessible from methods on a specific instance of a specific class. But it is hard to understand why you would want / need to go to that level of confinement. (And it is liable to lead to storage leaks ...)
Short answer: if you don't want your thread local variables to be accessible, restrict access to the ThreadLocal object.
Only local variables are on a thread's stack.* Static variables and instance variables both live on the heap. If we wanted to, we could also just pass a ThreadLocal around by itself without it ever living inside an object or class.
We could view ThreadLocal as a local variable which could be accessible at any point in time.
Normal local variables are destroyed when the scope they are declared in returns, but a ThreadLocal can live anywhere.
So my question is, is there ever a multi-threading scenario where ThreadLocal can/needs to be applied to non-static fields?
We can make one up...
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 share the same instance of Gadget but has their own local Dial.
Why then do we need ThreadLocal?
The truth is we don't need ThreadLocal very often, if at all.
* Only local variables are on a thread's stack except in the case of a theoretical optimization the JVM is allowed to do where objects can be stack allocated. We would never find out about this if it happened because it would not be allowed to change the behavior of the program. If an object is shared between threads, it's on the heap.
static ThreadLocal<Whatever> threadLocal;
Declares a field that points to an instance of class ThreadLocal. Each Thread has a Map<ThreadLocal<?>, Object> that associates instances of ThreadLocal with the value the corresponding "thread local variable" has for this Thread. That is, each ThreadLocal instance identifies a "thread local variable", and as far as the JVM is concerned, ThreadLocal is a class like any other.
Usually, when we need a "thread local variable", we only need a single one, and therefore create only a single ThreadLocal instance, which is often kept in a static field for convenient access.
If we need a new "thread local variable" for every instance of the host object, we could simply create a new ThreadLocal instance for every host object, and store in an a non-static field. Off hand, I can't think of a case where this is the simplest solution, but we could do it.
Threadlocal is a container for a set of variables each one of which is only available to one thread, ie it provides an instance of the contained class for each thread. So the ThreadLocal object is globally available (spending on permissions) but each instance of the contained class is only locally available to the thread.
This means that it needs to be initialized and destroyed for each thread slightly differently but in all other ways it is the same as any other variable.
Note : The point of destroying instances is to prevent memory leaks or leakage of state between independent invocations on the same thread if threads are being drawn from a pool.
Thread local variables are often used to provide a thread safe option for storage where there is no need for communication between threads. One such example is to define a new scope in CDI where that scope will exist wholly within a single thread (eg you could define an asynchronous request scope).
As such there is no need to restrict it to static or non-static variables as long as it is accessible where it is needed. In a default java environment Static variables are a convenient way of providing such access but in CDI a Singleton bean can provide the same level of access with many advantages.
In the injected singleton case the singleton bean would contain a nonstatic reference to the ThreadLocal and provide services to access the instances contained therein. Both the references to the injected singleton and the singleton's reference to the ThreadLocal would be non static.
So I have a Singleton class and in it a non-static public method that is called by multiple threads. In the non-static method I have local references to objects created by a Stored Procedure which I surmise means the 'new' keyword gets called somewhere.
1 public void someMethod(SomeObjectParameter parameter) {
2
3 Thing thingOne = synchornizedStoredProcedureCall():
4 doSomethingWith(thingOne);
5 doSomethingElseWith(thingOne);
6
7 }
Currently lines 3 through 5 are in a synchronized code block which I would like to reduce down to just having the stored procedure call as synchronized.
So... Say we have two threads, Thread1 and Thread2. Thread1 is about to execute line 3 and Thread2 is about to execute line 4. Since this is a local reference, will each thread maintain a different reference or will synchornizedStoredProcedureCall overwrite the reference to thingOne as doSomethingWith is about to use it?
What if thingOne is declared final or if I made it immutable?
will each thread maintain a different reference or will synchornizedStoredProcedureCall overwrite the reference to thingOne as doSomethingWith is about to use it?
The different threads have different stacks. The thingOne is stored in the per-thread stack so cannot be overwritten by the other thread. You also need to make sure that the synchornizedStoredProcedureCall() is returning a different instance of Thing each time and not a static or instance variable. Both threads need to be working on different Thing instances.
As long as the doSomethingWith(...) and doSomethingElseWith(...) calls are thread safe and only work with thingOne argument and constants (etc), protecting just the synchornizedStoredProcedureCall() should be fine.
As #Marko points out, without seeing the Thing class, we cannot be guaranteed that it is thread-safe and not storing internal state.
The answer depends on a lot of details that you haven't presented. Many details about the Thing class matter: it could have some internally shared state that may not be thread-safe (see the Flyweight design pattern). These facts must be documented in the class Javadoc; otherwise it would be very difficult to find it out from source code.
Thingone is thread safe anyway as it is declared threadlocal on the stack. If thingone was an instance variable not declared within a method, you would have problems; but it isn;t - so you don't.
your thingOne is local variable. it is thread safe. Each thread gets its own copy of locals.
You need to be sure that thingOne is not shared. Even though it is returned from a synchronized method, if it is a member of the singleton returned from synchornizedStoredProcedureCall , your implementation is no longer thread safe.
Each thread will maintain a different reference. That would be even the case if someMethod was static.
You still have to be sure that the Thing instances are thread safe themslef. E.g. the Thing class doesn't have static fields nor the two Thing instance have a non-static field pointing to the same object, or if they do they handle them in a thread safe way.
Method-Local inner class cannot access local variables because the instance of the method-local inner class may still alive after the method is over. But local variables will vanish once the local method is over.
I learned that method-local inner class can access final local variable, does this mean final local variable still alive after the method is over?
Sort of. Java anonymous inner classes act like "closures," that is, they "close" around the current local state. However, Java only lets these classes close around final variables. If it didn't, the local state of the variable could change, but the version held in the inner class would not, so it would be accessing an "out of date" instance. This could be confusing to a programmer.
Instead, Java requires that mutability be handled by the instance through methods, not variable reassignment. This leads to better clarity and allows for simpler debugging. For more information about why Java does this, see this answer.
Since the class still holds a reference to the variable, the answer to your question is yes, that instance will not be garbage collected until the inner class relinquishes ownership of the variable.
No it doesn't. It means that a copy of the local variable is still alive, in the inner class instance. The 'final' just makes sure the two copies don't confusingly diverge in value.